mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-03 16:30:29 +00:00
Compare commits
No commits in common. "master" and "4.0.2" have entirely different histories.
58 changed files with 152 additions and 1318 deletions
42
.github/workflows/build.yml
vendored
42
.github/workflows/build.yml
vendored
|
@ -1,8 +1,5 @@
|
||||||
name: build
|
name: build
|
||||||
|
|
||||||
env:
|
|
||||||
COSMOCC_VERSION: 3.9.2
|
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
@ -22,48 +19,13 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
mode: ["", tiny, rel, tinylinux, optlinux]
|
mode: ["", tiny, rel, tinylinux, optlinux]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
with:
|
|
||||||
# Full checkout needed for git-restore-mtime-bare.
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
# TODO(jart): fork this action.
|
|
||||||
- uses: chetan/git-restore-mtime-action@v2
|
|
||||||
|
|
||||||
- uses: actions/cache/restore@v4
|
|
||||||
id: cache
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
.cosmocc
|
|
||||||
o
|
|
||||||
key: ${{ env.COSMOCC_VERSION }}-${{ matrix.mode }}-${{ github.sha }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ env.COSMOCC_VERSION }}-${{ matrix.mode }}-
|
|
||||||
${{ env.COSMOCC_VERSION }}-
|
|
||||||
|
|
||||||
- name: Restore mtimes
|
|
||||||
if: steps.cache.outputs.cache-hit == 'true'
|
|
||||||
run: |
|
|
||||||
while read mtime file; do
|
|
||||||
[ -f "$file" ] && touch -d "@$mtime" "$file"
|
|
||||||
done < o/.mtimes
|
|
||||||
|
|
||||||
- name: support ape bins 1
|
- name: support ape bins 1
|
||||||
run: sudo cp -a build/bootstrap/ape.elf /usr/bin/ape
|
run: sudo cp build/bootstrap/ape.elf /usr/bin/ape
|
||||||
|
|
||||||
- name: support ape bins 2
|
- name: support ape bins 2
|
||||||
run: sudo sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register"
|
run: sudo sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register"
|
||||||
|
|
||||||
- name: make matrix
|
- name: make matrix
|
||||||
run: V=0 make -j2 MODE=${{ matrix.mode }}
|
run: V=0 make -j2 MODE=${{ matrix.mode }}
|
||||||
|
|
||||||
- name: Save mtimes
|
|
||||||
run: |
|
|
||||||
find o -type f -exec stat -c "%Y %n" {} \; > o/.mtimes
|
|
||||||
|
|
||||||
- uses: actions/cache/save@v4
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
.cosmocc
|
|
||||||
o
|
|
||||||
key: ${{ env.COSMOCC_VERSION }}-${{ matrix.mode }}-${{ github.sha }}
|
|
||||||
|
|
5
Makefile
5
Makefile
|
@ -77,8 +77,7 @@ COMMA := ,
|
||||||
PWD := $(shell pwd)
|
PWD := $(shell pwd)
|
||||||
|
|
||||||
# detect wsl2 running cosmopolitan binaries on the host by checking whether:
|
# detect wsl2 running cosmopolitan binaries on the host by checking whether:
|
||||||
# - user ran .cosmocc/current/bin/make, in which case make's working directory
|
# - user ran build/bootstrap/make, in which case make's working directory is in wsl
|
||||||
# is in wsl
|
|
||||||
# - user ran make, in which case cocmd's working directory is in wsl
|
# - user ran make, in which case cocmd's working directory is in wsl
|
||||||
ifneq ($(findstring //wsl.localhost/,$(CURDIR) $(PWD)),)
|
ifneq ($(findstring //wsl.localhost/,$(CURDIR) $(PWD)),)
|
||||||
$(warning wsl2 interop is enabled)
|
$(warning wsl2 interop is enabled)
|
||||||
|
@ -90,7 +89,7 @@ UNAME_S := $(shell uname -s)
|
||||||
|
|
||||||
# apple still distributes a 17 year old version of gnu make
|
# apple still distributes a 17 year old version of gnu make
|
||||||
ifeq ($(MAKE_VERSION), 3.81)
|
ifeq ($(MAKE_VERSION), 3.81)
|
||||||
$(error please use https://cosmo.zip/pub/cosmos/bin/make)
|
$(error please use build/bootstrap/make)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LC_ALL = C
|
LC_ALL = C
|
||||||
|
|
25
README.md
25
README.md
|
@ -3,7 +3,7 @@
|
||||||
[](https://github.com/jart/cosmopolitan/actions/workflows/build.yml)
|
[](https://github.com/jart/cosmopolitan/actions/workflows/build.yml)
|
||||||
# Cosmopolitan
|
# Cosmopolitan
|
||||||
|
|
||||||
[Cosmopolitan Libc](https://justine.lol/cosmopolitan/index.html) makes C/C++
|
[Cosmopolitan Libc](https://justine.lol/cosmopolitan/index.html) makes C
|
||||||
a build-once run-anywhere language, like Java, except it doesn't need an
|
a build-once run-anywhere language, like Java, except it doesn't need an
|
||||||
interpreter or virtual machine. Instead, it reconfigures stock GCC and
|
interpreter or virtual machine. Instead, it reconfigures stock GCC and
|
||||||
Clang to output a POSIX-approved polyglot format that runs natively on
|
Clang to output a POSIX-approved polyglot format that runs natively on
|
||||||
|
@ -87,22 +87,15 @@ ape/apeinstall.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
You can now build the mono repo with any modern version of GNU Make. To
|
You can now build the mono repo with any modern version of GNU Make. To
|
||||||
bootstrap your build, you can install Cosmopolitan Make from this site:
|
make life easier, we've included one in the cosmocc toolchain, which is
|
||||||
|
guaranteed to be compatible and furthermore includes our extensions for
|
||||||
https://cosmo.zip/pub/cosmos/bin/make
|
doing build system sandboxing.
|
||||||
|
|
||||||
E.g.:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl -LO https://cosmo.zip/pub/cosmos/bin/make
|
build/bootstrap/make -j8
|
||||||
./make -j8
|
|
||||||
o//examples/hello
|
o//examples/hello
|
||||||
```
|
```
|
||||||
|
|
||||||
After you've built the repo once, you can also use the make from your
|
|
||||||
cosmocc at `.cosmocc/current/bin/make`. You might even prefer to alias
|
|
||||||
make to `$COSMO/.cosmocc/current/bin/make`.
|
|
||||||
|
|
||||||
Since the Cosmopolitan repository is very large, you might only want to
|
Since the Cosmopolitan repository is very large, you might only want to
|
||||||
build one particular thing. Here's an example of a target that can be
|
build one particular thing. Here's an example of a target that can be
|
||||||
compiled relatively quickly, which is a simple POSIX test that only
|
compiled relatively quickly, which is a simple POSIX test that only
|
||||||
|
@ -110,7 +103,7 @@ depends on core LIBC packages.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
rm -rf o//libc o//test
|
rm -rf o//libc o//test
|
||||||
.cosmocc/current/bin/make o//test/posix/signal_test
|
build/bootstrap/make o//test/posix/signal_test
|
||||||
o//test/posix/signal_test
|
o//test/posix/signal_test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -119,21 +112,21 @@ list out each individual one. For example if you wanted to build and run
|
||||||
all the unit tests in the `TEST_POSIX` package, you could say:
|
all the unit tests in the `TEST_POSIX` package, you could say:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
.cosmocc/current/bin/make o//test/posix
|
build/bootstrap/make o//test/posix
|
||||||
```
|
```
|
||||||
|
|
||||||
Cosmopolitan provides a variety of build modes. For example, if you want
|
Cosmopolitan provides a variety of build modes. For example, if you want
|
||||||
really tiny binaries (as small as 12kb in size) then you'd say:
|
really tiny binaries (as small as 12kb in size) then you'd say:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
.cosmocc/current/bin/make m=tiny
|
build/bootstrap/make m=tiny
|
||||||
```
|
```
|
||||||
|
|
||||||
You can furthermore cut out the bloat of other operating systems, and
|
You can furthermore cut out the bloat of other operating systems, and
|
||||||
have Cosmopolitan become much more similar to Musl Libc.
|
have Cosmopolitan become much more similar to Musl Libc.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
.cosmocc/current/bin/make m=tinylinux
|
build/bootstrap/make m=tinylinux
|
||||||
```
|
```
|
||||||
|
|
||||||
For further details, see [//build/config.mk](build/config.mk).
|
For further details, see [//build/config.mk](build/config.mk).
|
||||||
|
|
|
@ -259,9 +259,6 @@ SECTIONS {
|
||||||
.debug_ranges 0 : { *(.debug_ranges) }
|
.debug_ranges 0 : { *(.debug_ranges) }
|
||||||
.debug_macro 0 : { *(.debug_macro) }
|
.debug_macro 0 : { *(.debug_macro) }
|
||||||
.debug_addr 0 : { *(.debug_addr) }
|
.debug_addr 0 : { *(.debug_addr) }
|
||||||
.debug_names 0 : { *(.debug_names) }
|
|
||||||
.debug_loclists 0 : { *(.debug_loclists) }
|
|
||||||
.debug_str_offsets 0 : { *(.debug_str_offsets) }
|
|
||||||
.ARM.attributes 0 : { KEEP(*(.ARM.attributes)) KEEP(*(.gnu.attributes)) }
|
.ARM.attributes 0 : { KEEP(*(.ARM.attributes)) KEEP(*(.gnu.attributes)) }
|
||||||
.note.gnu.arm.ident 0 : { KEEP(*(.note.gnu.arm.ident)) }
|
.note.gnu.arm.ident 0 : { KEEP(*(.note.gnu.arm.ident)) }
|
||||||
|
|
||||||
|
|
24
ape/ape.lds
24
ape/ape.lds
|
@ -386,13 +386,6 @@ SECTIONS {
|
||||||
_tbss_end = .;
|
_tbss_end = .;
|
||||||
} :Tls
|
} :Tls
|
||||||
|
|
||||||
.eh_frame : {
|
|
||||||
__eh_frame_start = .;
|
|
||||||
KEEP(*(.eh_frame))
|
|
||||||
*(.eh_frame.*)
|
|
||||||
__eh_frame_end = .;
|
|
||||||
} :Ram
|
|
||||||
|
|
||||||
.data . : {
|
.data . : {
|
||||||
/*BEGIN: Read/Write Data */
|
/*BEGIN: Read/Write Data */
|
||||||
#if SupportsWindows()
|
#if SupportsWindows()
|
||||||
|
@ -433,6 +426,11 @@ SECTIONS {
|
||||||
KEEP(*(.dtors))
|
KEEP(*(.dtors))
|
||||||
__fini_array_end = .;
|
__fini_array_end = .;
|
||||||
|
|
||||||
|
__eh_frame_start = .;
|
||||||
|
KEEP(*(.eh_frame))
|
||||||
|
*(.eh_frame.*)
|
||||||
|
__eh_frame_end = .;
|
||||||
|
|
||||||
/*BEGIN: Post-Initialization Read-Only */
|
/*BEGIN: Post-Initialization Read-Only */
|
||||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
||||||
KEEP(*(SORT_BY_NAME(.piro.relo.sort.*)))
|
KEEP(*(SORT_BY_NAME(.piro.relo.sort.*)))
|
||||||
|
@ -441,6 +439,7 @@ SECTIONS {
|
||||||
KEEP(*(.piro.pad.data))
|
KEEP(*(.piro.pad.data))
|
||||||
*(.igot.plt)
|
*(.igot.plt)
|
||||||
KEEP(*(.dataepilogue))
|
KEEP(*(.dataepilogue))
|
||||||
|
|
||||||
. = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
|
. = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
|
||||||
/*END: NT FORK COPYING */
|
/*END: NT FORK COPYING */
|
||||||
_edata = .;
|
_edata = .;
|
||||||
|
@ -520,9 +519,6 @@ SECTIONS {
|
||||||
.debug_rnglists 0 : { *(.debug_rnglists) }
|
.debug_rnglists 0 : { *(.debug_rnglists) }
|
||||||
.debug_macro 0 : { *(.debug_macro) }
|
.debug_macro 0 : { *(.debug_macro) }
|
||||||
.debug_addr 0 : { *(.debug_addr) }
|
.debug_addr 0 : { *(.debug_addr) }
|
||||||
.debug_names 0 : { *(.debug_names) }
|
|
||||||
.debug_loclists 0 : { *(.debug_loclists) }
|
|
||||||
.debug_str_offsets 0 : { *(.debug_str_offsets) }
|
|
||||||
.gnu.attributes 0 : { KEEP(*(.gnu.attributes)) }
|
.gnu.attributes 0 : { KEEP(*(.gnu.attributes)) }
|
||||||
.GCC.command.line 0 : { *(.GCC.command.line) }
|
.GCC.command.line 0 : { *(.GCC.command.line) }
|
||||||
|
|
||||||
|
@ -586,11 +582,11 @@ ape_rom_memsz = ape_rom_filesz;
|
||||||
ape_rom_align = CONSTANT(COMMONPAGESIZE);
|
ape_rom_align = CONSTANT(COMMONPAGESIZE);
|
||||||
ape_rom_rva = RVA(ape_rom_vaddr);
|
ape_rom_rva = RVA(ape_rom_vaddr);
|
||||||
|
|
||||||
ape_ram_vaddr = ADDR(.eh_frame);
|
ape_ram_vaddr = ADDR(.data);
|
||||||
ape_ram_offset = ape_ram_vaddr - __executable_start;
|
ape_ram_offset = ape_ram_vaddr - __executable_start;
|
||||||
ape_ram_paddr = LOADADDR(.eh_frame);
|
ape_ram_paddr = LOADADDR(.data);
|
||||||
ape_ram_filesz = ADDR(.bss) - ADDR(.eh_frame);
|
ape_ram_filesz = ADDR(.bss) - ADDR(.data);
|
||||||
ape_ram_memsz = _end - ADDR(.eh_frame);
|
ape_ram_memsz = _end - ADDR(.data);
|
||||||
ape_ram_align = CONSTANT(COMMONPAGESIZE);
|
ape_ram_align = CONSTANT(COMMONPAGESIZE);
|
||||||
ape_ram_rva = RVA(ape_ram_vaddr);
|
ape_ram_rva = RVA(ape_ram_vaddr);
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ if [ ! -f ape/loader.c ]; then
|
||||||
cd "$COSMO" || exit
|
cd "$COSMO" || exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -x .cosmocc/current/bin/make ]; then
|
if [ -x build/bootstrap/make ]; then
|
||||||
MAKE=.cosmocc/current/bin/make
|
MAKE=build/bootstrap/make
|
||||||
else
|
else
|
||||||
MAKE=make
|
MAKE=make
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -99,8 +99,3 @@ rm -f cosmocc.zip cosmocc.zip.sha256sum
|
||||||
# commit output directory
|
# commit output directory
|
||||||
cd "${OLDPWD}" || die
|
cd "${OLDPWD}" || die
|
||||||
mv "${OUTPUT_TMP}" "${OUTPUT_DIR}" || die
|
mv "${OUTPUT_TMP}" "${OUTPUT_DIR}" || die
|
||||||
|
|
||||||
# update current symlink
|
|
||||||
BASE=$(basename "${OUTPUT_DIR}")
|
|
||||||
DIR=$(dirname "${OUTPUT_DIR}")
|
|
||||||
ln -sfn "$BASE" "$DIR/current"
|
|
||||||
|
|
|
@ -97,12 +97,12 @@ class shared_ref
|
||||||
|
|
||||||
size_t use_count() const noexcept
|
size_t use_count() const noexcept
|
||||||
{
|
{
|
||||||
return __atomic_load_n(&shared, __ATOMIC_RELAXED) + 1;
|
return shared + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t weak_count() const noexcept
|
size_t weak_count() const noexcept
|
||||||
{
|
{
|
||||||
return __atomic_load_n(&weak, __ATOMIC_RELAXED);
|
return weak;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -349,7 +349,7 @@ class shared_ptr
|
||||||
template<typename U>
|
template<typename U>
|
||||||
bool owner_before(const weak_ptr<U>& r) const noexcept
|
bool owner_before(const weak_ptr<U>& r) const noexcept
|
||||||
{
|
{
|
||||||
return rc < r.rc;
|
return !r.owner_before(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -382,34 +382,6 @@ class weak_ptr
|
||||||
rc->keep_weak();
|
rc->keep_weak();
|
||||||
}
|
}
|
||||||
|
|
||||||
weak_ptr(const weak_ptr& r) noexcept : p(r.p), rc(r.rc)
|
|
||||||
{
|
|
||||||
if (rc)
|
|
||||||
rc->keep_weak();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
requires __::shared_ptr_compatible<T, U>
|
|
||||||
weak_ptr(const weak_ptr<U>& r) noexcept : p(r.p), rc(r.rc)
|
|
||||||
{
|
|
||||||
if (rc)
|
|
||||||
rc->keep_weak();
|
|
||||||
}
|
|
||||||
|
|
||||||
weak_ptr(weak_ptr&& r) noexcept : p(r.p), rc(r.rc)
|
|
||||||
{
|
|
||||||
r.p = nullptr;
|
|
||||||
r.rc = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
requires __::shared_ptr_compatible<T, U>
|
|
||||||
weak_ptr(weak_ptr<U>&& r) noexcept : p(r.p), rc(r.rc)
|
|
||||||
{
|
|
||||||
r.p = nullptr;
|
|
||||||
r.rc = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
~weak_ptr()
|
~weak_ptr()
|
||||||
{
|
{
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -438,19 +410,6 @@ class weak_ptr
|
||||||
swap(rc, r.rc);
|
swap(rc, r.rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
weak_ptr& operator=(weak_ptr r) noexcept
|
|
||||||
{
|
|
||||||
swap(r);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
requires __::shared_ptr_compatible<T, U>
|
|
||||||
weak_ptr& operator=(weak_ptr<U> r) noexcept
|
|
||||||
{
|
|
||||||
weak_ptr<T>(move(r)).swap(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<T> lock() const noexcept
|
shared_ptr<T> lock() const noexcept
|
||||||
{
|
{
|
||||||
if (expired())
|
if (expired())
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
// @return rdi is rdi+edx
|
// @return rdi is rdi+edx
|
||||||
.text.startup
|
.text.startup
|
||||||
__getntsyspath:
|
__getntsyspath:
|
||||||
beg
|
push %rbp
|
||||||
pro
|
mov %rsp,%rbp
|
||||||
push %rdx
|
push %rdx
|
||||||
movpp %rdi,%rcx # call f=%rax(p1=%rcx,p2=%rdx)
|
movpp %rdi,%rcx # call f=%rax(p1=%rcx,p2=%rdx)
|
||||||
sub $40,%rsp
|
sub $40,%rsp
|
||||||
|
@ -55,7 +55,6 @@ __getntsyspath:
|
||||||
jne 2f
|
jne 2f
|
||||||
movb $'/',-1(%rdi)
|
movb $'/',-1(%rdi)
|
||||||
2: .loop 1b
|
2: .loop 1b
|
||||||
epi
|
leave
|
||||||
ret
|
ret
|
||||||
end
|
|
||||||
.endfn __getntsyspath,globl,hidden
|
.endfn __getntsyspath,globl,hidden
|
||||||
|
|
|
@ -114,8 +114,7 @@ static ssize_t GetDevUrandom(char *p, size_t n, unsigned f) {
|
||||||
ssize_t __getrandom(void *p, size_t n, unsigned f) {
|
ssize_t __getrandom(void *p, size_t n, unsigned f) {
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
if (IsWindows()) {
|
if (IsWindows()) {
|
||||||
ProcessPrng(p, n); // never fails
|
rc = ProcessPrng(p, n) ? n : __winerr();
|
||||||
rc = n;
|
|
||||||
} else if (have_getrandom) {
|
} else if (have_getrandom) {
|
||||||
if (IsXnu() || IsOpenbsd()) {
|
if (IsXnu() || IsOpenbsd()) {
|
||||||
rc = GetRandomBsd(p, n, GetRandomEntropy);
|
rc = GetRandomBsd(p, n, GetRandomEntropy);
|
||||||
|
@ -185,7 +184,9 @@ ssize_t __getrandom(void *p, size_t n, unsigned f) {
|
||||||
* @raise EFAULT if the `n` bytes at `p` aren't valid memory
|
* @raise EFAULT if the `n` bytes at `p` aren't valid memory
|
||||||
* @raise EINTR if we needed to block and a signal was delivered instead
|
* @raise EINTR if we needed to block and a signal was delivered instead
|
||||||
* @cancelationpoint
|
* @cancelationpoint
|
||||||
|
* @asyncsignalsafe
|
||||||
* @restartable
|
* @restartable
|
||||||
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
ssize_t getrandom(void *p, size_t n, unsigned f) {
|
ssize_t getrandom(void *p, size_t n, unsigned f) {
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
|
|
|
@ -694,7 +694,6 @@ static const uint16_t kPledgeStdio[] = {
|
||||||
__NR_linux_sched_getaffinity, //
|
__NR_linux_sched_getaffinity, //
|
||||||
__NR_linux_sched_setaffinity, //
|
__NR_linux_sched_setaffinity, //
|
||||||
__NR_linux_sigtimedwait, //
|
__NR_linux_sigtimedwait, //
|
||||||
__NR_linux_getcpu, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeFlock[] = {
|
static const uint16_t kPledgeFlock[] = {
|
||||||
|
|
|
@ -997,10 +997,8 @@ textwindows ssize_t ReadBuffer(int fd, void *data, size_t size, int64_t offset,
|
||||||
if (f->kind == kFdDevNull)
|
if (f->kind == kFdDevNull)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (f->kind == kFdDevRandom) {
|
if (f->kind == kFdDevRandom)
|
||||||
ProcessPrng(data, size);
|
return ProcessPrng(data, size) ? size : __winerr();
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f->kind == kFdConsole)
|
if (f->kind == kFdConsole)
|
||||||
return ReadFromConsole(f, data, size, waitmask);
|
return ReadFromConsole(f, data, size, waitmask);
|
||||||
|
|
|
@ -423,7 +423,7 @@ static int __sigaction(int sig, const struct sigaction *act,
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* void ContinueOnCrash(void) {
|
* void ContinueOnCrash(void) {
|
||||||
* struct sigaction sa = {.sa_sigaction = OnCrash,
|
* struct sigaction sa = {.sa_handler = OnSigSegv,
|
||||||
* .sa_flags = SA_SIGINFO | SA_RESETHAND};
|
* .sa_flags = SA_SIGINFO | SA_RESETHAND};
|
||||||
* sigaction(SIGSEGV, &sa, 0);
|
* sigaction(SIGSEGV, &sa, 0);
|
||||||
* sigaction(SIGFPE, &sa, 0);
|
* sigaction(SIGFPE, &sa, 0);
|
||||||
|
|
|
@ -47,14 +47,7 @@ __oops_win32:
|
||||||
// @note ape.S and ape-loader both set RCX to XNU on Darwin
|
// @note ape.S and ape-loader both set RCX to XNU on Darwin
|
||||||
// @noreturn
|
// @noreturn
|
||||||
_start:
|
_start:
|
||||||
.cfi_startproc
|
#ifdef __x86_64__
|
||||||
#if defined(__x86_64__)
|
|
||||||
.cfi_undefined rip
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
.cfi_undefined x30
|
|
||||||
#endif /* __x86_64__ */
|
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
|
|
||||||
#if SupportsFreebsd()
|
#if SupportsFreebsd()
|
||||||
// detect free besiyata dishmaya
|
// detect free besiyata dishmaya
|
||||||
|
@ -166,5 +159,4 @@ _start:
|
||||||
#else
|
#else
|
||||||
#error "architecture unsupported"
|
#error "architecture unsupported"
|
||||||
#endif /* __x86_64__ */
|
#endif /* __x86_64__ */
|
||||||
.cfi_endproc
|
|
||||||
.endfn _start,weak,hidden
|
.endfn _start,weak,hidden
|
||||||
|
|
|
@ -68,7 +68,6 @@
|
||||||
#define EM_NONE 0
|
#define EM_NONE 0
|
||||||
#define EM_M32 1
|
#define EM_M32 1
|
||||||
#define EM_386 3
|
#define EM_386 3
|
||||||
#define EM_MIPS 8
|
|
||||||
#define EM_PPC64 21
|
#define EM_PPC64 21
|
||||||
#define EM_S390 22
|
#define EM_S390 22
|
||||||
#define EM_ARM 40
|
#define EM_ARM 40
|
||||||
|
|
|
@ -21,15 +21,16 @@
|
||||||
.privileged
|
.privileged
|
||||||
|
|
||||||
cosmo_futex_thunk:
|
cosmo_futex_thunk:
|
||||||
beg
|
|
||||||
pro
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
mov %rcx,%r10
|
mov %rcx,%r10
|
||||||
mov __NR_futex,%eax
|
mov __NR_futex,%eax
|
||||||
clc
|
clc
|
||||||
syscall
|
syscall
|
||||||
jnc 1f
|
jnc 1f
|
||||||
neg %eax
|
neg %eax
|
||||||
|
1: pop %rbp
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
ldr x7,=__hostos
|
ldr x7,=__hostos
|
||||||
ldr w7,[x7]
|
ldr w7,[x7]
|
||||||
|
@ -45,7 +46,5 @@ cosmo_futex_thunk:
|
||||||
#else
|
#else
|
||||||
#error "unsupported architecture"
|
#error "unsupported architecture"
|
||||||
#endif /* __x86_64__ */
|
#endif /* __x86_64__ */
|
||||||
1: epi
|
1: ret
|
||||||
ret
|
|
||||||
end
|
|
||||||
.endfn cosmo_futex_thunk,globl,hidden
|
.endfn cosmo_futex_thunk,globl,hidden
|
||||||
|
|
|
@ -26,9 +26,7 @@
|
||||||
// @see setcontext()
|
// @see setcontext()
|
||||||
.ftrace1
|
.ftrace1
|
||||||
getcontext:
|
getcontext:
|
||||||
beg
|
|
||||||
.ftrace2
|
.ftrace2
|
||||||
#include "libc/intrin/getcontext.inc"
|
#include "libc/intrin/getcontext.inc"
|
||||||
jmp __getcontextsig
|
jmp __getcontextsig
|
||||||
end
|
|
||||||
.endfn getcontext,globl
|
.endfn getcontext,globl
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
// usually better that sigprocmask only strace the user is calling it.
|
// usually better that sigprocmask only strace the user is calling it.
|
||||||
// plus, since we have a very specific use case, this code goes faster
|
// plus, since we have a very specific use case, this code goes faster
|
||||||
|
|
||||||
|
struct Signals __sig;
|
||||||
|
|
||||||
sigset_t __sig_block(void) {
|
sigset_t __sig_block(void) {
|
||||||
if (IsWindows() || IsMetal()) {
|
if (IsWindows() || IsMetal()) {
|
||||||
if (__tls_enabled)
|
if (__tls_enabled)
|
||||||
|
|
|
@ -31,17 +31,17 @@
|
||||||
// @returnstwice
|
// @returnstwice
|
||||||
.ftrace1
|
.ftrace1
|
||||||
swapcontext:
|
swapcontext:
|
||||||
beg
|
|
||||||
.ftrace2
|
.ftrace2
|
||||||
#include "libc/intrin/getcontext.inc"
|
#include "libc/intrin/getcontext.inc"
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
pro
|
push %rbp
|
||||||
cpush %rsi
|
mov %rsp,%rbp
|
||||||
cpush %rsi
|
push %rsi
|
||||||
|
push %rsi
|
||||||
call __swapcontextsig
|
call __swapcontextsig
|
||||||
cpop %rdi
|
pop %rdi
|
||||||
cpop %rdi
|
pop %rdi
|
||||||
epi
|
pop %rbp
|
||||||
test %eax,%eax
|
test %eax,%eax
|
||||||
jnz 1f
|
jnz 1f
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
|
@ -56,5 +56,4 @@ swapcontext:
|
||||||
#endif
|
#endif
|
||||||
jmp __tailcontext
|
jmp __tailcontext
|
||||||
1: ret
|
1: ret
|
||||||
end
|
|
||||||
.endfn swapcontext,globl
|
.endfn swapcontext,globl
|
||||||
|
|
|
@ -24,9 +24,9 @@
|
||||||
//
|
//
|
||||||
// @return 0 on success, or -1 w/ errno
|
// @return 0 on success, or -1 w/ errno
|
||||||
sys_sched_yield:
|
sys_sched_yield:
|
||||||
beg
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
pro
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
xor %eax,%eax
|
xor %eax,%eax
|
||||||
mov __hostos(%rip),%dl
|
mov __hostos(%rip),%dl
|
||||||
|
|
||||||
|
@ -84,16 +84,13 @@ sys_sched_yield:
|
||||||
// fails a positive or negative errno might get returned.
|
// fails a positive or negative errno might get returned.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
9: epi
|
9: leave
|
||||||
ret
|
ret
|
||||||
|
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
|
|
||||||
stp x29,x30,[sp,-32]!
|
stp x29,x30,[sp,-32]!
|
||||||
mov x29,sp
|
mov x29,sp
|
||||||
.cfi_adjust_cfa_offset 32
|
|
||||||
.cfi_rel_offset x29,16
|
|
||||||
.cfi_rel_offset x30,24
|
|
||||||
mov x3,0
|
mov x3,0
|
||||||
mov x2,0
|
mov x2,0
|
||||||
add x4,sp,16
|
add x4,sp,16
|
||||||
|
@ -104,14 +101,10 @@ sys_sched_yield:
|
||||||
mov x16,#0x5d // select(0,0,0,0,&blah) for xnu
|
mov x16,#0x5d // select(0,0,0,0,&blah) for xnu
|
||||||
svc 0
|
svc 0
|
||||||
ldp x29,x30,[sp],32
|
ldp x29,x30,[sp],32
|
||||||
.cfi_adjust_cfa_offset -32
|
|
||||||
.cfi_restore x30
|
|
||||||
.cfi_restore x29
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "arch unsupported"
|
#error "arch unsupported"
|
||||||
#endif
|
#endif
|
||||||
end
|
|
||||||
.endfn sys_sched_yield,globl
|
.endfn sys_sched_yield,globl
|
||||||
.previous
|
.previous
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include "libc/nt/files.h"
|
#include "libc/nt/files.h"
|
||||||
#include "libc/nt/ipc.h"
|
#include "libc/nt/ipc.h"
|
||||||
#include "libc/nt/memory.h"
|
#include "libc/nt/memory.h"
|
||||||
#include "libc/nt/nls.h"
|
|
||||||
#include "libc/nt/paint.h"
|
#include "libc/nt/paint.h"
|
||||||
#include "libc/nt/process.h"
|
#include "libc/nt/process.h"
|
||||||
#include "libc/nt/registry.h"
|
#include "libc/nt/registry.h"
|
||||||
|
@ -1421,15 +1420,6 @@
|
||||||
#define HKEY_CURRENT_CONFIG kNtHkeyCurrentConfig
|
#define HKEY_CURRENT_CONFIG kNtHkeyCurrentConfig
|
||||||
#define HKEY_DYN_DATA kNtHkeyDynData
|
#define HKEY_DYN_DATA kNtHkeyDynData
|
||||||
#define HKEY_CURRENT_USER_LOCAL_SETTINGS kNtHkeyCurrentUserLocalSettings
|
#define HKEY_CURRENT_USER_LOCAL_SETTINGS kNtHkeyCurrentUserLocalSettings
|
||||||
#define KEY_QUERY_VALUE kNtKeyQueryValue
|
|
||||||
#define KEY_SET_VALUE kNtKeySetValue
|
|
||||||
#define KEY_CREATE_SUB_KEY kNtKeyCreateSubKey
|
|
||||||
#define KEY_ENUMERATE_SUB_KEYS kNtKeyEnumerateSubKeys
|
|
||||||
#define KEY_NOTIFY kNtKeyNotify
|
|
||||||
#define KEY_CREATE_LINK kNtKeyCreateLink
|
|
||||||
#define KEY_WOW64_32KEY kNtWow6432Key
|
|
||||||
#define KEY_WOW64_64KEY kNtWow6464Key
|
|
||||||
#define KEY_WOW64_RES kNtWow64Res
|
|
||||||
#define KEY_READ kNtKeyRead
|
#define KEY_READ kNtKeyRead
|
||||||
#define KEY_WRITE kNtKeyWrite
|
#define KEY_WRITE kNtKeyWrite
|
||||||
#define KEY_EXECUTE kNtKeyExecute
|
#define KEY_EXECUTE kNtKeyExecute
|
||||||
|
@ -4301,13 +4291,6 @@
|
||||||
#define MAKE_HRESULT(sev,fac,code) ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) )
|
#define MAKE_HRESULT(sev,fac,code) ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) )
|
||||||
#define MAKE_SCODE(sev,fac,code) ((SCODE) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) )
|
#define MAKE_SCODE(sev,fac,code) ((SCODE) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) )
|
||||||
|
|
||||||
#define CP_ACP 0
|
|
||||||
#define CP_OEMCP 1
|
|
||||||
#define CP_MACCP 2
|
|
||||||
#define CP_THREAD_ACP 3
|
|
||||||
#define CP_SYMBOL 42
|
|
||||||
|
|
||||||
#define CP_UTF7 65000
|
|
||||||
#define CP_UTF8 65001
|
#define CP_UTF8 65001
|
||||||
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_COMPAT_INCLUDE_WINDOWS_H_ */
|
#endif /* COSMOPOLITAN_LIBC_COMPAT_INCLUDE_WINDOWS_H_ */
|
||||||
|
|
|
@ -158,60 +158,6 @@
|
||||||
.weak \canonical
|
.weak \canonical
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro beg
|
|
||||||
.cfi_startproc
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro pro
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
push %rbp
|
|
||||||
.cfi_adjust_cfa_offset 8
|
|
||||||
.cfi_rel_offset %rbp,0
|
|
||||||
mov %rsp,%rbp
|
|
||||||
.cfi_def_cfa_register %rbp
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
stp x29,x30,[sp,-16]!
|
|
||||||
mov x29,sp
|
|
||||||
.cfi_adjust_cfa_offset 16
|
|
||||||
.cfi_rel_offset x29,0
|
|
||||||
.cfi_rel_offset x30,8
|
|
||||||
#else
|
|
||||||
#error "unsupported architecture"
|
|
||||||
#endif
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro epi
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
.cfi_def_cfa_register %rsp
|
|
||||||
leave
|
|
||||||
.cfi_adjust_cfa_offset -8
|
|
||||||
.cfi_restore %rbp
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
ldp x29,x30,[sp],#16
|
|
||||||
.cfi_adjust_cfa_offset -16
|
|
||||||
.cfi_restore x30
|
|
||||||
.cfi_restore x29
|
|
||||||
#else
|
|
||||||
#error "unsupported architecture"
|
|
||||||
#endif
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro end
|
|
||||||
.cfi_endproc
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro cpush reg:req
|
|
||||||
push \reg
|
|
||||||
.cfi_adjust_cfa_offset 8
|
|
||||||
.cfi_rel_offset \reg,0
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro cpop reg:req
|
|
||||||
pop \reg
|
|
||||||
.cfi_adjust_cfa_offset -8
|
|
||||||
.cfi_restore \reg
|
|
||||||
.endm
|
|
||||||
|
|
||||||
#ifdef __aarch64__
|
#ifdef __aarch64__
|
||||||
.macro jmp dest:req
|
.macro jmp dest:req
|
||||||
b \dest
|
b \dest
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
// @note public domain
|
// @note public domain
|
||||||
// @see en.wikipedia.org/wiki/Sorting_network
|
// @see en.wikipedia.org/wiki/Sorting_network
|
||||||
djbsort_avx2:
|
djbsort_avx2:
|
||||||
beg
|
push %rbp
|
||||||
pro
|
mov %rsp,%rbp
|
||||||
push %r15
|
push %r15
|
||||||
push %r14
|
push %r14
|
||||||
push %r13
|
push %r13
|
||||||
|
@ -795,13 +795,11 @@ djbsort_avx2:
|
||||||
pop %r13
|
pop %r13
|
||||||
pop %r14
|
pop %r14
|
||||||
pop %r15
|
pop %r15
|
||||||
epi
|
pop %rbp
|
||||||
ret
|
ret
|
||||||
end
|
|
||||||
.endfn djbsort_avx2,globl,hidden
|
.endfn djbsort_avx2,globl,hidden
|
||||||
|
|
||||||
minmax_vector:
|
minmax_vector:
|
||||||
beg
|
|
||||||
cmp $7,%rdx
|
cmp $7,%rdx
|
||||||
jg .L13
|
jg .L13
|
||||||
.L2: test %rdx,%rdx
|
.L2: test %rdx,%rdx
|
||||||
|
@ -840,11 +838,9 @@ minmax_vector:
|
||||||
sub $8,%rdx
|
sub $8,%rdx
|
||||||
jne .L7
|
jne .L7
|
||||||
ret
|
ret
|
||||||
end
|
|
||||||
.endfn minmax_vector
|
.endfn minmax_vector
|
||||||
|
|
||||||
int32_twostages_32:
|
int32_twostages_32:
|
||||||
beg
|
|
||||||
sub $-128,%rdi
|
sub $-128,%rdi
|
||||||
.L17: lea -128(%rdi),%rax
|
.L17: lea -128(%rdi),%rax
|
||||||
test %rsi,%rsi
|
test %rsi,%rsi
|
||||||
|
@ -870,14 +866,13 @@ int32_twostages_32:
|
||||||
add $512,%rdi
|
add $512,%rdi
|
||||||
jmp .L17
|
jmp .L17
|
||||||
.L21: ret
|
.L21: ret
|
||||||
end
|
|
||||||
.endfn int32_twostages_32
|
.endfn int32_twostages_32
|
||||||
|
|
||||||
int32_threestages:
|
int32_threestages:
|
||||||
beg
|
push %rbp
|
||||||
pro
|
|
||||||
imul $-24,%rdx,%r8
|
imul $-24,%rdx,%r8
|
||||||
lea 0(,%rdx,8),%rax
|
lea 0(,%rdx,8),%rax
|
||||||
|
mov %rsp,%rbp
|
||||||
push %r15
|
push %r15
|
||||||
push %r14
|
push %r14
|
||||||
push %r13
|
push %r13
|
||||||
|
@ -966,13 +961,11 @@ int32_threestages:
|
||||||
pop %r13
|
pop %r13
|
||||||
pop %r14
|
pop %r14
|
||||||
pop %r15
|
pop %r15
|
||||||
epi
|
pop %rbp
|
||||||
ret
|
ret
|
||||||
end
|
|
||||||
.endfn int32_threestages
|
.endfn int32_threestages
|
||||||
|
|
||||||
merge16_finish:
|
merge16_finish:
|
||||||
beg
|
|
||||||
vpminsd %ymm1,%ymm0,%ymm3
|
vpminsd %ymm1,%ymm0,%ymm3
|
||||||
vpmaxsd %ymm1,%ymm0,%ymm0
|
vpmaxsd %ymm1,%ymm0,%ymm0
|
||||||
vperm2i128 $32,%ymm0,%ymm3,%ymm2
|
vperm2i128 $32,%ymm0,%ymm3,%ymm2
|
||||||
|
@ -1001,11 +994,9 @@ merge16_finish:
|
||||||
.L31: vmovdqu %ymm2,(%rdi)
|
.L31: vmovdqu %ymm2,(%rdi)
|
||||||
vmovdqu %ymm0,32(%rdi)
|
vmovdqu %ymm0,32(%rdi)
|
||||||
ret
|
ret
|
||||||
end
|
|
||||||
.endfn merge16_finish
|
.endfn merge16_finish
|
||||||
|
|
||||||
int32_sort_2power:
|
int32_sort_2power:
|
||||||
beg
|
|
||||||
push %r13
|
push %r13
|
||||||
lea 16(%rsp),%r13
|
lea 16(%rsp),%r13
|
||||||
andq $-32,%rsp
|
andq $-32,%rsp
|
||||||
|
@ -2084,7 +2075,6 @@ int32_sort_2power:
|
||||||
lea -16(%r13),%rsp
|
lea -16(%r13),%rsp
|
||||||
pop %r13
|
pop %r13
|
||||||
ret
|
ret
|
||||||
end
|
|
||||||
.endfn int32_sort_2power
|
.endfn int32_sort_2power
|
||||||
|
|
||||||
.rodata.cst32
|
.rodata.cst32
|
||||||
|
|
|
@ -32,8 +32,7 @@
|
||||||
// @param rax,rdx,xmm0,xmm1,st0,st1 is return value
|
// @param rax,rdx,xmm0,xmm1,st0,st1 is return value
|
||||||
// @see test/libc/runtime/gc_test.c
|
// @see test/libc/runtime/gc_test.c
|
||||||
.ftrace1
|
.ftrace1
|
||||||
__gc: beg
|
__gc: .ftrace2
|
||||||
.ftrace2
|
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
|
|
||||||
|
@ -48,7 +47,8 @@ __gc: beg
|
||||||
mov 8(%r8),%r9
|
mov 8(%r8),%r9
|
||||||
mov 16(%r8),%rdi
|
mov 16(%r8),%rdi
|
||||||
push 24(%r8)
|
push 24(%r8)
|
||||||
pro
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
sub $32,%rsp
|
sub $32,%rsp
|
||||||
mov %rax,-8(%rbp)
|
mov %rax,-8(%rbp)
|
||||||
mov %rdx,-16(%rbp)
|
mov %rdx,-16(%rbp)
|
||||||
|
@ -57,7 +57,7 @@ __gc: beg
|
||||||
movdqa -32(%rbp),%xmm0
|
movdqa -32(%rbp),%xmm0
|
||||||
mov -16(%rbp),%rdx
|
mov -16(%rbp),%rdx
|
||||||
mov -8(%rbp),%rax
|
mov -8(%rbp),%rax
|
||||||
epi
|
leave
|
||||||
ret
|
ret
|
||||||
9: ud2
|
9: ud2
|
||||||
nop
|
nop
|
||||||
|
@ -102,5 +102,4 @@ __gc: beg
|
||||||
|
|
||||||
#endif /* __x86_64__ */
|
#endif /* __x86_64__ */
|
||||||
|
|
||||||
end
|
|
||||||
.endfn __gc,globl,hidden
|
.endfn __gc,globl,hidden
|
||||||
|
|
|
@ -31,9 +31,7 @@
|
||||||
// @noreturn
|
// @noreturn
|
||||||
.ftrace1
|
.ftrace1
|
||||||
gclongjmp:
|
gclongjmp:
|
||||||
beg
|
|
||||||
.ftrace2
|
.ftrace2
|
||||||
pro
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
|
@ -67,5 +65,4 @@ gclongjmp:
|
||||||
#else
|
#else
|
||||||
#error "unsupported architecture"
|
#error "unsupported architecture"
|
||||||
#endif /* __x86_64__ */
|
#endif /* __x86_64__ */
|
||||||
end
|
|
||||||
.endfn gclongjmp,globl
|
.endfn gclongjmp,globl
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
// @see gclongjmp()
|
// @see gclongjmp()
|
||||||
// @see siglongjmp()
|
// @see siglongjmp()
|
||||||
.ftrace1
|
.ftrace1
|
||||||
longjmp:beg
|
longjmp:
|
||||||
.ftrace2
|
.ftrace2
|
||||||
_longjmp:
|
_longjmp:
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
|
@ -61,7 +61,6 @@ _longjmp:
|
||||||
#else
|
#else
|
||||||
#error "unsupported architecture"
|
#error "unsupported architecture"
|
||||||
#endif
|
#endif
|
||||||
end
|
|
||||||
.endfn longjmp,globl
|
.endfn longjmp,globl
|
||||||
.endfn _longjmp,globl
|
.endfn _longjmp,globl
|
||||||
.alias longjmp,siglongjmp
|
.alias longjmp,siglongjmp
|
||||||
|
|
|
@ -30,8 +30,8 @@
|
||||||
// @note slower than __sysv2nt
|
// @note slower than __sysv2nt
|
||||||
// @see NT2SYSV() macro
|
// @see NT2SYSV() macro
|
||||||
__nt2sysv:
|
__nt2sysv:
|
||||||
beg
|
push %rbp
|
||||||
pro
|
mov %rsp,%rbp
|
||||||
sub $256,%rsp
|
sub $256,%rsp
|
||||||
push %rbx
|
push %rbx
|
||||||
push %rdi
|
push %rdi
|
||||||
|
@ -48,7 +48,6 @@ __nt2sysv:
|
||||||
pop %rsi
|
pop %rsi
|
||||||
pop %rdi
|
pop %rdi
|
||||||
pop %rbx
|
pop %rbx
|
||||||
epi
|
leave
|
||||||
ret
|
ret
|
||||||
end
|
|
||||||
.endfn __nt2sysv,globl,hidden
|
.endfn __nt2sysv,globl,hidden
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
#include "libc/nt/codegen.h"
|
|
||||||
.imp advapi32,__imp_RegOpenKeyExA,RegOpenKeyExA
|
|
||||||
|
|
||||||
.text.windows
|
|
||||||
.ftrace1
|
|
||||||
RegOpenKeyExA:
|
|
||||||
.ftrace2
|
|
||||||
#ifdef __x86_64__
|
|
||||||
push %rbp
|
|
||||||
mov %rsp,%rbp
|
|
||||||
mov __imp_RegOpenKeyExA(%rip),%rax
|
|
||||||
jmp __sysv2nt6
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
mov x0,#0
|
|
||||||
ret
|
|
||||||
#endif
|
|
||||||
.endfn RegOpenKeyExA,globl
|
|
||||||
.previous
|
|
|
@ -1,16 +1,6 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_NT_ENUM_KEYACCESS_H_
|
#ifndef COSMOPOLITAN_LIBC_NT_ENUM_KEYACCESS_H_
|
||||||
#define COSMOPOLITAN_LIBC_NT_ENUM_KEYACCESS_H_
|
#define COSMOPOLITAN_LIBC_NT_ENUM_KEYACCESS_H_
|
||||||
|
|
||||||
#define kNtKeyQueryValue 0x00000001
|
|
||||||
#define kNtKeySetValue 0x00000002
|
|
||||||
#define kNtKeyCreateSubKey 0x00000004
|
|
||||||
#define kNtKeyEnumerateSubKeys 0x00000008
|
|
||||||
#define kNtKeyNotify 0x00000010
|
|
||||||
#define kNtKeyCreateLink 0x00000020
|
|
||||||
#define kNtWow6432Key 0x00000200
|
|
||||||
#define kNtWow6464Key 0x00000100
|
|
||||||
#define kNtWow64Res 0x00000300
|
|
||||||
|
|
||||||
#define kNtKeyRead 0x00020019
|
#define kNtKeyRead 0x00020019
|
||||||
#define kNtKeyWrite 0x00020006
|
#define kNtKeyWrite 0x00020006
|
||||||
#define kNtKeyExecute 0x00020019
|
#define kNtKeyExecute 0x00020019
|
||||||
|
|
|
@ -49,7 +49,6 @@ COSMOPOLITAN_C_START_
|
||||||
intptr_t LoadResource(int64_t hModule, int64_t hResInfo);
|
intptr_t LoadResource(int64_t hModule, int64_t hResInfo);
|
||||||
uint32_t SetHandleCount(uint32_t uNumber);
|
uint32_t SetHandleCount(uint32_t uNumber);
|
||||||
uint32_t GetLogicalDrives(void);
|
uint32_t GetLogicalDrives(void);
|
||||||
uint32_t GetLogicalDriveStringsA(uint32_t nBufferLength, char *lpBuffer);
|
|
||||||
bool32 FlushFileBuffers(int64_t hFile);
|
bool32 FlushFileBuffers(int64_t hFile);
|
||||||
|
|
||||||
int64_t ReOpenFile(int64_t hOriginalFile, uint32_t dwDesiredAccess,
|
int64_t ReOpenFile(int64_t hOriginalFile, uint32_t dwDesiredAccess,
|
||||||
|
@ -206,7 +205,6 @@ uint32_t GetFinalPathNameByHandle(int64_t hFile, char16_t *out_path,
|
||||||
|
|
||||||
uint32_t GetFullPathName(const char16_t *lpFileName, uint32_t nBufferLength,
|
uint32_t GetFullPathName(const char16_t *lpFileName, uint32_t nBufferLength,
|
||||||
char16_t *lpBuffer, char16_t **lpFilePart);
|
char16_t *lpBuffer, char16_t **lpFilePart);
|
||||||
uint32_t GetShortPathName(const char16_t *lpszLongPath, char16_t *out_lpszShortPath, uint32_t cchBuffer);
|
|
||||||
|
|
||||||
bool32 GetOverlappedResult(int64_t hFile, struct NtOverlapped *lpOverlapped,
|
bool32 GetOverlappedResult(int64_t hFile, struct NtOverlapped *lpOverlapped,
|
||||||
uint32_t *lpNumberOfBytesTransferred, bool32 bWait);
|
uint32_t *lpNumberOfBytesTransferred, bool32 bWait);
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
#include "libc/nt/codegen.h"
|
|
||||||
.imp kernel32,__imp_GetACP,GetACP
|
|
||||||
|
|
||||||
.text.windows
|
|
||||||
.ftrace1
|
|
||||||
GetACP:
|
|
||||||
.ftrace2
|
|
||||||
#ifdef __x86_64__
|
|
||||||
push %rbp
|
|
||||||
mov %rsp,%rbp
|
|
||||||
sub $32,%rsp
|
|
||||||
call *__imp_GetACP(%rip)
|
|
||||||
leave
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
mov x0,#0
|
|
||||||
#endif
|
|
||||||
ret
|
|
||||||
.endfn GetACP,globl
|
|
||||||
.previous
|
|
|
@ -1,18 +0,0 @@
|
||||||
#include "libc/nt/codegen.h"
|
|
||||||
.imp kernel32,__imp_GetCPInfoExW,GetCPInfoExW
|
|
||||||
|
|
||||||
.text.windows
|
|
||||||
.ftrace1
|
|
||||||
GetCPInfoEx:
|
|
||||||
.ftrace2
|
|
||||||
#ifdef __x86_64__
|
|
||||||
push %rbp
|
|
||||||
mov %rsp,%rbp
|
|
||||||
mov __imp_GetCPInfoExW(%rip),%rax
|
|
||||||
jmp __sysv2nt
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
mov x0,#0
|
|
||||||
ret
|
|
||||||
#endif
|
|
||||||
.endfn GetCPInfoEx,globl
|
|
||||||
.previous
|
|
|
@ -1,18 +0,0 @@
|
||||||
#include "libc/nt/codegen.h"
|
|
||||||
.imp kernel32,__imp_GetLogicalDriveStringsA,GetLogicalDriveStringsA
|
|
||||||
|
|
||||||
.text.windows
|
|
||||||
.ftrace1
|
|
||||||
GetLogicalDriveStringsA:
|
|
||||||
.ftrace2
|
|
||||||
#ifdef __x86_64__
|
|
||||||
push %rbp
|
|
||||||
mov %rsp,%rbp
|
|
||||||
mov __imp_GetLogicalDriveStringsA(%rip),%rax
|
|
||||||
jmp __sysv2nt
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
mov x0,#0
|
|
||||||
ret
|
|
||||||
#endif
|
|
||||||
.endfn GetLogicalDriveStringsA,globl
|
|
||||||
.previous
|
|
|
@ -1,19 +0,0 @@
|
||||||
#include "libc/nt/codegen.h"
|
|
||||||
.imp kernel32,__imp_GetOEMCP,GetOEMCP
|
|
||||||
|
|
||||||
.text.windows
|
|
||||||
.ftrace1
|
|
||||||
GetOEMCP:
|
|
||||||
.ftrace2
|
|
||||||
#ifdef __x86_64__
|
|
||||||
push %rbp
|
|
||||||
mov %rsp,%rbp
|
|
||||||
sub $32,%rsp
|
|
||||||
call *__imp_GetOEMCP(%rip)
|
|
||||||
leave
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
mov x0,#0
|
|
||||||
#endif
|
|
||||||
ret
|
|
||||||
.endfn GetOEMCP,globl
|
|
||||||
.previous
|
|
|
@ -1,18 +0,0 @@
|
||||||
#include "libc/nt/codegen.h"
|
|
||||||
.imp kernel32,__imp_GetShortPathNameW,GetShortPathNameW
|
|
||||||
|
|
||||||
.text.windows
|
|
||||||
.ftrace1
|
|
||||||
GetShortPathName:
|
|
||||||
.ftrace2
|
|
||||||
#ifdef __x86_64__
|
|
||||||
push %rbp
|
|
||||||
mov %rsp,%rbp
|
|
||||||
mov __imp_GetShortPathNameW(%rip),%rax
|
|
||||||
jmp __sysv2nt
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
mov x0,#0
|
|
||||||
ret
|
|
||||||
#endif
|
|
||||||
.endfn GetShortPathName,globl
|
|
||||||
.previous
|
|
|
@ -129,12 +129,10 @@ imp 'GetFileTime' GetFileTime kernel32 4
|
||||||
imp 'GetFileType' GetFileType kernel32 1
|
imp 'GetFileType' GetFileType kernel32 1
|
||||||
imp 'GetFinalPathNameByHandle' GetFinalPathNameByHandleW kernel32 4
|
imp 'GetFinalPathNameByHandle' GetFinalPathNameByHandleW kernel32 4
|
||||||
imp 'GetFullPathName' GetFullPathNameW kernel32 4
|
imp 'GetFullPathName' GetFullPathNameW kernel32 4
|
||||||
imp 'GetShortPathName' GetShortPathNameW kernel32 3
|
|
||||||
imp 'GetHandleInformation' GetHandleInformation kernel32 2
|
imp 'GetHandleInformation' GetHandleInformation kernel32 2
|
||||||
imp 'GetLargestConsoleWindowSize' GetLargestConsoleWindowSize kernel32 1
|
imp 'GetLargestConsoleWindowSize' GetLargestConsoleWindowSize kernel32 1
|
||||||
imp 'GetLastError' GetLastError kernel32 0
|
imp 'GetLastError' GetLastError kernel32 0
|
||||||
imp 'GetLogicalDrives' GetLogicalDrives kernel32 0
|
imp 'GetLogicalDrives' GetLogicalDrives kernel32 0
|
||||||
imp 'GetLogicalDriveStringsA' GetLogicalDriveStringsA kernel32 2
|
|
||||||
imp 'GetMaximumProcessorCount' GetMaximumProcessorCount kernel32 1 # Windows 7+
|
imp 'GetMaximumProcessorCount' GetMaximumProcessorCount kernel32 1 # Windows 7+
|
||||||
imp 'GetModuleFileName' GetModuleFileNameW kernel32 3
|
imp 'GetModuleFileName' GetModuleFileNameW kernel32 3
|
||||||
imp 'GetModuleHandle' GetModuleHandleA kernel32 1
|
imp 'GetModuleHandle' GetModuleHandleA kernel32 1
|
||||||
|
@ -188,9 +186,6 @@ imp 'GetVolumeInformationByHandle' GetVolumeInformationByHandleW kernel32
|
||||||
imp 'GetVolumePathName' GetVolumePathNameW kernel32 3
|
imp 'GetVolumePathName' GetVolumePathNameW kernel32 3
|
||||||
imp 'GetWindowsDirectory' GetWindowsDirectoryW kernel32 2
|
imp 'GetWindowsDirectory' GetWindowsDirectoryW kernel32 2
|
||||||
imp 'GetWindowsDirectoryA' GetWindowsDirectoryA kernel32 2
|
imp 'GetWindowsDirectoryA' GetWindowsDirectoryA kernel32 2
|
||||||
imp 'GetOEMCP' GetOEMCP kernel32 0
|
|
||||||
imp 'GetACP' GetACP kernel32 0
|
|
||||||
imp 'GetCPInfoEx' GetCPInfoExW kernel32 3
|
|
||||||
imp 'GlobalAlloc' GlobalAlloc kernel32 2
|
imp 'GlobalAlloc' GlobalAlloc kernel32 2
|
||||||
imp 'GlobalFree' GlobalFree kernel32 1
|
imp 'GlobalFree' GlobalFree kernel32 1
|
||||||
imp 'GlobalLock' GlobalLock kernel32 1
|
imp 'GlobalLock' GlobalLock kernel32 1
|
||||||
|
@ -361,7 +356,6 @@ imp 'RegLoadKey' RegLoadKeyW advapi32 3
|
||||||
imp 'RegNotifyChangeKeyValue' RegNotifyChangeKeyValue advapi32 5
|
imp 'RegNotifyChangeKeyValue' RegNotifyChangeKeyValue advapi32 5
|
||||||
imp 'RegOpenCurrentUser' RegOpenCurrentUser advapi32 2
|
imp 'RegOpenCurrentUser' RegOpenCurrentUser advapi32 2
|
||||||
imp 'RegOpenKeyEx' RegOpenKeyExW advapi32 5
|
imp 'RegOpenKeyEx' RegOpenKeyExW advapi32 5
|
||||||
imp 'RegOpenKeyExA' RegOpenKeyExA advapi32 5
|
|
||||||
imp 'RegOpenUserClassesRoot' RegOpenUserClassesRoot advapi32 4
|
imp 'RegOpenUserClassesRoot' RegOpenUserClassesRoot advapi32 4
|
||||||
imp 'RegOverridePredefKey' RegOverridePredefKey advapi32 2
|
imp 'RegOverridePredefKey' RegOverridePredefKey advapi32 2
|
||||||
imp 'RegQueryInfoKey' RegQueryInfoKeyW advapi32 12
|
imp 'RegQueryInfoKey' RegQueryInfoKeyW advapi32 12
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_NT_NLS_H_
|
|
||||||
#define COSMOPOLITAN_LIBC_NT_NLS_H_
|
|
||||||
#include "libc/nt/struct/cpinfoex.h"
|
|
||||||
/* ░░░░
|
|
||||||
▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░
|
|
||||||
▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░
|
|
||||||
▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░
|
|
||||||
▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█
|
|
||||||
▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓
|
|
||||||
░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█
|
|
||||||
▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓
|
|
||||||
▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒
|
|
||||||
▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█
|
|
||||||
▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓
|
|
||||||
░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█
|
|
||||||
▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓
|
|
||||||
░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓
|
|
||||||
▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████
|
|
||||||
▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███
|
|
||||||
▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███
|
|
||||||
▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██
|
|
||||||
▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██
|
|
||||||
▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███
|
|
||||||
░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██
|
|
||||||
╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗
|
|
||||||
│ cosmopolitan § new technology » internationalization ─╬─│┼
|
|
||||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
|
||||||
COSMOPOLITAN_C_START_
|
|
||||||
|
|
||||||
uint32_t GetOEMCP();
|
|
||||||
uint32_t GetACP();
|
|
||||||
bool32 GetCPInfoEx(uint32_t CodePage, uint32_t dwFlags, struct NtCpInfoEx *out_lpCPInfoEx) paramsnonnull((3));
|
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_NT_NLS_H_ */
|
|
|
@ -51,8 +51,6 @@ int RegOpenKey(int64_t hKey, const char16_t *opt_lpSubKey,
|
||||||
int RegOpenKeyEx(int64_t hKey, const char16_t *opt_lpSubKey,
|
int RegOpenKeyEx(int64_t hKey, const char16_t *opt_lpSubKey,
|
||||||
uint32_t opt_ulOptions, int samDesired, int64_t *out_phkResult)
|
uint32_t opt_ulOptions, int samDesired, int64_t *out_phkResult)
|
||||||
paramsnonnull((5));
|
paramsnonnull((5));
|
||||||
int RegOpenKeyExA(int64_t hKey, const char *opt_lpSubKey, uint32_t opt_ulOptions,
|
|
||||||
int samDesired, int64_t *out_phkResult) paramsnonnull((5));
|
|
||||||
int RegCloseKey(int64_t hKey);
|
int RegCloseKey(int64_t hKey);
|
||||||
|
|
||||||
int RegGetValue(int64_t hkey, const char16_t *opt_lpSubKey,
|
int RegGetValue(int64_t hkey, const char16_t *opt_lpSubKey,
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_CPINFOEX_H_
|
|
||||||
#define COSMOPOLITAN_LIBC_NT_STRUCT_CPINFOEX_H_
|
|
||||||
|
|
||||||
struct NtCpInfoEx {
|
|
||||||
uint32_t MaxCharSize;
|
|
||||||
uint8_t DefaultChar[2];
|
|
||||||
uint8_t LeadByte[12];
|
|
||||||
char16_t UnicodeDefaultChar;
|
|
||||||
uint32_t CodePage;
|
|
||||||
char16_t CodePageName[260];
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_CPINFOEX_H_ */
|
|
|
@ -30,18 +30,18 @@
|
||||||
// @param 8(rsp) x6 is arg
|
// @param 8(rsp) x6 is arg
|
||||||
// @return tid of child on success, or -errno on error
|
// @return tid of child on success, or -errno on error
|
||||||
sys_clone_linux:
|
sys_clone_linux:
|
||||||
beg
|
|
||||||
pro
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
cpush %rbx
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
push %rbx
|
||||||
mov %rcx,%r10
|
mov %rcx,%r10
|
||||||
mov 16(%rbp),%rbx
|
mov 16(%rbp),%rbx
|
||||||
mov $56,%eax // __NR_clone
|
mov $56,%eax // __NR_clone
|
||||||
syscall
|
syscall
|
||||||
test %rax,%rax
|
test %rax,%rax
|
||||||
jz 2f
|
jz 2f
|
||||||
0: cpop %rbx
|
0: pop %rbx
|
||||||
epi
|
pop %rbp
|
||||||
ret
|
ret
|
||||||
2: xor %ebp,%ebp // child thread
|
2: xor %ebp,%ebp // child thread
|
||||||
mov %rbx,%rdi // arg
|
mov %rbx,%rdi // arg
|
||||||
|
@ -50,13 +50,15 @@ sys_clone_linux:
|
||||||
mov $60,%eax // __NR_exit(exitcode)
|
mov $60,%eax // __NR_exit(exitcode)
|
||||||
syscall
|
syscall
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
|
stp x29,x30,[sp,#-16]!
|
||||||
|
mov x29,sp
|
||||||
mov x8,x3 // swap x3 and x4
|
mov x8,x3 // swap x3 and x4
|
||||||
mov x3,x4 // swap x3 and x4
|
mov x3,x4 // swap x3 and x4
|
||||||
mov x4,x8 // swap x3 and x4
|
mov x4,x8 // swap x3 and x4
|
||||||
mov x8,#220 // __NR_clone
|
mov x8,#220 // __NR_clone
|
||||||
svc #0
|
svc #0
|
||||||
cbz x0,2f
|
cbz x0,2f
|
||||||
epi
|
ldp x29,x30,[sp],#16
|
||||||
ret
|
ret
|
||||||
2: mov x29,#0 // wipe backtrace
|
2: mov x29,#0 // wipe backtrace
|
||||||
mov x28,x3 // set cosmo tls
|
mov x28,x3 // set cosmo tls
|
||||||
|
@ -67,5 +69,4 @@ sys_clone_linux:
|
||||||
#else
|
#else
|
||||||
#error "unsupported architecture"
|
#error "unsupported architecture"
|
||||||
#endif
|
#endif
|
||||||
end
|
|
||||||
.endfn sys_clone_linux,globl,hidden
|
.endfn sys_clone_linux,globl,hidden
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
// @param rdx is environ
|
// @param rdx is environ
|
||||||
// @param rcx is auxv
|
// @param rcx is auxv
|
||||||
// @noreturn
|
// @noreturn
|
||||||
cosmo: beg
|
cosmo: push %rbp
|
||||||
pro
|
mov %rsp,%rbp
|
||||||
mov %edi,%r12d
|
mov %edi,%r12d
|
||||||
mov %rsi,%r13
|
mov %rsi,%r13
|
||||||
mov %rdx,%r14
|
mov %rdx,%r14
|
||||||
|
@ -104,10 +104,7 @@ cosmo: beg
|
||||||
je 2f
|
je 2f
|
||||||
push %rax
|
push %rax
|
||||||
push %rax
|
push %rax
|
||||||
mov %r12d,%edi
|
call .Largs
|
||||||
mov %r13,%rsi
|
|
||||||
mov %r14,%rdx
|
|
||||||
mov %r15,%rcx
|
|
||||||
call *(%rax)
|
call *(%rax)
|
||||||
pop %rax
|
pop %rax
|
||||||
pop %rax
|
pop %rax
|
||||||
|
@ -115,15 +112,17 @@ cosmo: beg
|
||||||
jmp 1b
|
jmp 1b
|
||||||
|
|
||||||
// call main()
|
// call main()
|
||||||
2: mov %r12d,%edi
|
2: call .Largs
|
||||||
mov %r13,%rsi
|
|
||||||
mov %r14,%rdx
|
|
||||||
mov %r15,%rcx
|
|
||||||
.weak main
|
.weak main
|
||||||
call main
|
call main
|
||||||
xchg %eax,%edi
|
xchg %eax,%edi
|
||||||
call exit
|
call exit
|
||||||
end
|
|
||||||
|
.Largs: mov %r12d,%edi
|
||||||
|
mov %r13,%rsi
|
||||||
|
mov %r14,%rdx
|
||||||
|
mov %r15,%rcx
|
||||||
|
ret
|
||||||
.endfn cosmo,weak
|
.endfn cosmo,weak
|
||||||
|
|
||||||
// Enables Thread Local Storage.
|
// Enables Thread Local Storage.
|
||||||
|
|
|
@ -28,12 +28,8 @@ ftrace_hook:
|
||||||
|
|
||||||
cmpl $0,__ftrace(%rip)
|
cmpl $0,__ftrace(%rip)
|
||||||
jle 1f
|
jle 1f
|
||||||
.cfi_startproc
|
|
||||||
push %rbp
|
push %rbp
|
||||||
.cfi_def_cfa_offset 16
|
|
||||||
.cfi_offset %rbp, -16
|
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.cfi_def_cfa_register %rbp
|
|
||||||
and $-16,%rsp
|
and $-16,%rsp
|
||||||
sub $128,%rsp
|
sub $128,%rsp
|
||||||
movdqu %xmm0,-0x80(%rbp)
|
movdqu %xmm0,-0x80(%rbp)
|
||||||
|
@ -45,21 +41,13 @@ ftrace_hook:
|
||||||
movdqu %xmm6,-0x20(%rbp)
|
movdqu %xmm6,-0x20(%rbp)
|
||||||
movdqu %xmm7,-0x10(%rbp)
|
movdqu %xmm7,-0x10(%rbp)
|
||||||
push %rax
|
push %rax
|
||||||
.cfi_offset %rax, -24
|
|
||||||
push %rcx
|
push %rcx
|
||||||
.cfi_offset %rcx, -32
|
|
||||||
push %rdx
|
push %rdx
|
||||||
.cfi_offset %rdx, -40
|
|
||||||
push %rdi
|
push %rdi
|
||||||
.cfi_offset %rdi, -48
|
|
||||||
push %rsi
|
push %rsi
|
||||||
.cfi_offset %rsi, -56
|
|
||||||
push %r8
|
push %r8
|
||||||
.cfi_offset %r8, -64
|
|
||||||
push %r9
|
push %r9
|
||||||
.cfi_offset %r9, -72
|
|
||||||
push %r10
|
push %r10
|
||||||
.cfi_offset %r10, -80
|
|
||||||
call ftracer
|
call ftracer
|
||||||
movdqu -0x80(%rbp),%xmm0
|
movdqu -0x80(%rbp),%xmm0
|
||||||
movdqu -0x70(%rbp),%xmm1
|
movdqu -0x70(%rbp),%xmm1
|
||||||
|
@ -78,20 +66,12 @@ ftrace_hook:
|
||||||
pop %rcx
|
pop %rcx
|
||||||
pop %rax
|
pop %rax
|
||||||
leave
|
leave
|
||||||
.cfi_restore %rbp
|
|
||||||
.cfi_def_cfa %rsp, 8
|
|
||||||
1: ret
|
1: ret
|
||||||
.cfi_endproc
|
|
||||||
|
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
|
|
||||||
stp x29,x30,[sp,-384]!
|
stp x29,x30,[sp,-384]!
|
||||||
.cfi_startproc
|
|
||||||
.cfi_def_cfa_offset 384
|
|
||||||
.cfi_offset 29, -384 // x29 (fp) is saved at [sp - 384]
|
|
||||||
.cfi_offset 30, -376 // x30 (lr) is saved at [sp - 376]
|
|
||||||
mov x29,sp
|
mov x29,sp
|
||||||
.cfi_def_cfa_register 29
|
|
||||||
stp x0,x1,[sp,16]
|
stp x0,x1,[sp,16]
|
||||||
|
|
||||||
adrp x0,__ftrace
|
adrp x0,__ftrace
|
||||||
|
@ -100,45 +80,18 @@ ftrace_hook:
|
||||||
ble 1f
|
ble 1f
|
||||||
|
|
||||||
stp x2,x3,[sp,32]
|
stp x2,x3,[sp,32]
|
||||||
.cfi_offset 2, -352
|
|
||||||
.cfi_offset 3, -344
|
|
||||||
stp x4,x5,[sp,48]
|
stp x4,x5,[sp,48]
|
||||||
.cfi_offset 4, -336
|
|
||||||
.cfi_offset 5, -328
|
|
||||||
stp x6,x7,[sp,64]
|
stp x6,x7,[sp,64]
|
||||||
.cfi_offset 6, -320
|
|
||||||
.cfi_offset 7, -312
|
|
||||||
stp x8,x9,[sp,80]
|
stp x8,x9,[sp,80]
|
||||||
.cfi_offset 8, -304
|
|
||||||
.cfi_offset 9, -296
|
|
||||||
stp x10,x11,[sp,96]
|
stp x10,x11,[sp,96]
|
||||||
.cfi_offset 10, -288
|
|
||||||
.cfi_offset 11, -280
|
|
||||||
stp x12,x13,[sp,112]
|
stp x12,x13,[sp,112]
|
||||||
.cfi_offset 12, -272
|
|
||||||
.cfi_offset 13, -264
|
|
||||||
stp x14,x15,[sp,128]
|
stp x14,x15,[sp,128]
|
||||||
.cfi_offset 14, -256
|
|
||||||
.cfi_offset 15, -248
|
|
||||||
stp x16,x19,[sp,160]
|
stp x16,x19,[sp,160]
|
||||||
.cfi_offset 16, -224
|
|
||||||
.cfi_offset 19, -216
|
|
||||||
stp x20,x21,[sp,176]
|
stp x20,x21,[sp,176]
|
||||||
.cfi_offset 20, -208
|
|
||||||
.cfi_offset 21, -200
|
|
||||||
stp x22,x23,[sp,192]
|
stp x22,x23,[sp,192]
|
||||||
.cfi_offset 22, -192
|
|
||||||
.cfi_offset 23, -184
|
|
||||||
stp x24,x25,[sp,208]
|
stp x24,x25,[sp,208]
|
||||||
.cfi_offset 24, -176
|
|
||||||
.cfi_offset 25, -168
|
|
||||||
stp x26,x27,[sp,224]
|
stp x26,x27,[sp,224]
|
||||||
.cfi_offset 26, -160
|
|
||||||
.cfi_offset 27, -152
|
|
||||||
stp x17,x28,[sp,240]
|
stp x17,x28,[sp,240]
|
||||||
.cfi_offset 17, -144
|
|
||||||
.cfi_offset 28, -136
|
|
||||||
// No CFI directives needed for FP registers
|
|
||||||
stp q0,q1,[sp,256]
|
stp q0,q1,[sp,256]
|
||||||
stp q2,q3,[sp,288]
|
stp q2,q3,[sp,288]
|
||||||
stp q4,q5,[sp,320]
|
stp q4,q5,[sp,320]
|
||||||
|
@ -166,12 +119,7 @@ ftrace_hook:
|
||||||
|
|
||||||
1: ldp x0,x1,[sp,16]
|
1: ldp x0,x1,[sp,16]
|
||||||
ldp x29,x30,[sp],384
|
ldp x29,x30,[sp],384
|
||||||
.cfi_restore 29
|
|
||||||
.cfi_restore 30
|
|
||||||
.cfi_def_cfa 7, 0 // On some ARM systems the stack pointer is represented by register 7
|
|
||||||
.cfi_def_cfa_offset 0
|
|
||||||
ret
|
ret
|
||||||
.cfi_endproc
|
|
||||||
|
|
||||||
#endif /* __x86_64__ */
|
#endif /* __x86_64__ */
|
||||||
.endfn ftrace_hook,globl,hidden
|
.endfn ftrace_hook,globl,hidden
|
||||||
|
|
|
@ -18,19 +18,13 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/sock/ifaddrs.h"
|
#include "libc/sock/ifaddrs.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/syscall-sysv.internal.h"
|
|
||||||
#include "libc/dce.h"
|
|
||||||
#include "libc/limits.h"
|
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
#include "libc/sock/struct/ifconf.h"
|
#include "libc/sock/struct/ifconf.h"
|
||||||
#include "libc/sock/struct/ifreq.h"
|
#include "libc/sock/struct/ifreq.h"
|
||||||
#include "libc/sock/struct/sockaddr6.h"
|
|
||||||
#include "libc/stdio/stdio.h"
|
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/af.h"
|
#include "libc/sysv/consts/af.h"
|
||||||
#include "libc/sysv/consts/iff.h"
|
#include "libc/sysv/consts/iff.h"
|
||||||
#include "libc/sysv/consts/o.h"
|
|
||||||
#include "libc/sysv/consts/sio.h"
|
#include "libc/sysv/consts/sio.h"
|
||||||
#include "libc/sysv/consts/sock.h"
|
#include "libc/sysv/consts/sock.h"
|
||||||
|
|
||||||
|
@ -42,20 +36,6 @@ struct IfAddr {
|
||||||
struct sockaddr_in bstaddr;
|
struct sockaddr_in bstaddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IfAddr6Info {
|
|
||||||
int addr_scope;
|
|
||||||
int addr_flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct IfAddr6 {
|
|
||||||
struct ifaddrs ifaddrs;
|
|
||||||
char name[IFNAMSIZ];
|
|
||||||
struct sockaddr_in6 addr;
|
|
||||||
struct sockaddr_in6 netmask;
|
|
||||||
struct sockaddr_in6 bstaddr; // unused
|
|
||||||
struct IfAddr6Info info;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees network interface address list.
|
* Frees network interface address list.
|
||||||
*/
|
*/
|
||||||
|
@ -68,73 +48,6 @@ void freeifaddrs(struct ifaddrs *ifp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// hex repr to network order int
|
|
||||||
static uint128_t hex2no(const char *str) {
|
|
||||||
uint128_t res = 0;
|
|
||||||
const int max_quads = sizeof(uint128_t) * 2;
|
|
||||||
int i = 0;
|
|
||||||
while ((i < max_quads) && str[i]) {
|
|
||||||
uint8_t acc = (((str[i] & 0xF) + (str[i] >> 6)) | ((str[i] >> 3) & 0x8));
|
|
||||||
acc = acc << 4;
|
|
||||||
i += 1;
|
|
||||||
if (str[i]) {
|
|
||||||
acc = acc | (((str[i] & 0xF) + (str[i] >> 6)) | ((str[i] >> 3) & 0x8));
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
res = (res >> 8) | (((uint128_t)acc) << ((sizeof(uint128_t) - 1) * 8));
|
|
||||||
}
|
|
||||||
res = res >> ((max_quads - i) * 4);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets network interface IPv6 address list on linux.
|
|
||||||
*
|
|
||||||
* @return 0 on success, or -1 w/ errno
|
|
||||||
*/
|
|
||||||
static int getifaddrs_linux_ip6(struct ifconf *conf) {
|
|
||||||
int fd;
|
|
||||||
int n = 0;
|
|
||||||
struct ifreq *ifreq = conf->ifc_req;
|
|
||||||
const int bufsz = 44 + IFNAMSIZ + 1;
|
|
||||||
char buf[bufsz + 1]; // one line max size
|
|
||||||
if ((fd = sys_openat(0, "/proc/net/if_inet6", O_RDONLY, 0)) == -1) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((n = sys_read(fd, &buf[n], bufsz - n)) &&
|
|
||||||
((char *)ifreq < (conf->ifc_buf + conf->ifc_len))) {
|
|
||||||
// flags linux include/uapi/linux/if_addr.h:44
|
|
||||||
// scope linux include/net/ipv6.h:L99
|
|
||||||
|
|
||||||
// *addr, *index, *plen, *scope, *flags, *ifname
|
|
||||||
char *s[] = {&buf[0], &buf[33], &buf[36], &buf[39], &buf[42], &buf[45]};
|
|
||||||
int ifnamelen = 0;
|
|
||||||
while (*s[5] == ' ') {
|
|
||||||
++s[5];
|
|
||||||
}
|
|
||||||
while (s[5][ifnamelen] > '\n') {
|
|
||||||
++ifnamelen;
|
|
||||||
}
|
|
||||||
buf[32] = buf[35] = buf[38] = buf[41] = buf[44] = s[5][ifnamelen] = '\0';
|
|
||||||
bzero(ifreq, sizeof(*ifreq));
|
|
||||||
ifreq->ifr_addr.sa_family = AF_INET6;
|
|
||||||
memcpy(&ifreq->ifr_name, s[5], ifnamelen);
|
|
||||||
*((uint128_t *)&ifreq->ifr6_addr) = hex2no(s[0]);
|
|
||||||
ifreq->ifr6_ifindex = hex2no(s[1]);
|
|
||||||
ifreq->ifr6_prefixlen = hex2no(s[2]);
|
|
||||||
ifreq->ifr6_scope = hex2no(s[3]);
|
|
||||||
ifreq->ifr6_flags = hex2no(s[4]);
|
|
||||||
++ifreq;
|
|
||||||
int tlen = &s[5][ifnamelen] - &buf[0] + 1;
|
|
||||||
n = bufsz - tlen;
|
|
||||||
memcpy(&buf, &buf[tlen], n);
|
|
||||||
}
|
|
||||||
|
|
||||||
conf->ifc_len = (char *)ifreq - conf->ifc_buf;
|
|
||||||
return sys_close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets network interface address list.
|
* Gets network interface address list.
|
||||||
*
|
*
|
||||||
|
@ -142,7 +55,6 @@ static int getifaddrs_linux_ip6(struct ifconf *conf) {
|
||||||
* @see tool/viz/getifaddrs.c for example code
|
* @see tool/viz/getifaddrs.c for example code
|
||||||
*/
|
*/
|
||||||
int getifaddrs(struct ifaddrs **out_ifpp) {
|
int getifaddrs(struct ifaddrs **out_ifpp) {
|
||||||
// printf("%d\n", sizeof(struct ifreq));
|
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
int fd;
|
int fd;
|
||||||
if ((fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0)) != -1) {
|
if ((fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0)) != -1) {
|
||||||
|
@ -153,88 +65,42 @@ int getifaddrs(struct ifaddrs **out_ifpp) {
|
||||||
conf.ifc_buf = data;
|
conf.ifc_buf = data;
|
||||||
conf.ifc_len = size;
|
conf.ifc_len = size;
|
||||||
if (!ioctl(fd, SIOCGIFCONF, &conf)) {
|
if (!ioctl(fd, SIOCGIFCONF, &conf)) {
|
||||||
if (IsLinux()) {
|
|
||||||
struct ifconf confl6;
|
|
||||||
confl6.ifc_buf = data + conf.ifc_len;
|
|
||||||
confl6.ifc_len = size - conf.ifc_len;
|
|
||||||
if ((rc = getifaddrs_linux_ip6(&confl6)))
|
|
||||||
return rc;
|
|
||||||
conf.ifc_len += confl6.ifc_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ifaddrs *res = 0;
|
struct ifaddrs *res = 0;
|
||||||
for (struct ifreq *ifr = (struct ifreq *)data;
|
for (struct ifreq *ifr = (struct ifreq *)data;
|
||||||
(char *)ifr < data + conf.ifc_len; ++ifr) {
|
(char *)ifr < data + conf.ifc_len; ++ifr) {
|
||||||
uint16_t family = ifr->ifr_addr.sa_family;
|
if (ifr->ifr_addr.sa_family != AF_INET) {
|
||||||
if (family == AF_INET) {
|
continue; // TODO(jart): IPv6 support
|
||||||
struct IfAddr *addr;
|
}
|
||||||
if ((addr = calloc(1, sizeof(struct IfAddr)))) {
|
struct IfAddr *addr;
|
||||||
memcpy(addr->name, ifr->ifr_name, IFNAMSIZ);
|
if ((addr = calloc(1, sizeof(struct IfAddr)))) {
|
||||||
addr->ifaddrs.ifa_name = addr->name;
|
memcpy(addr->name, ifr->ifr_name, IFNAMSIZ);
|
||||||
memcpy(&addr->addr, &ifr->ifr_addr, sizeof(struct sockaddr_in));
|
addr->ifaddrs.ifa_name = addr->name;
|
||||||
addr->ifaddrs.ifa_addr = (struct sockaddr *)&addr->addr;
|
memcpy(&addr->addr, &ifr->ifr_addr, sizeof(struct sockaddr_in));
|
||||||
addr->ifaddrs.ifa_netmask = (struct sockaddr *)&addr->netmask;
|
addr->ifaddrs.ifa_addr = (struct sockaddr *)&addr->addr;
|
||||||
if (!ioctl(fd, SIOCGIFFLAGS, ifr)) {
|
addr->ifaddrs.ifa_netmask = (struct sockaddr *)&addr->netmask;
|
||||||
addr->ifaddrs.ifa_flags = ifr->ifr_flags;
|
if (!ioctl(fd, SIOCGIFFLAGS, ifr)) {
|
||||||
}
|
addr->ifaddrs.ifa_flags = ifr->ifr_flags;
|
||||||
if (!ioctl(fd, SIOCGIFNETMASK, ifr)) {
|
|
||||||
memcpy(&addr->netmask, &ifr->ifr_addr,
|
|
||||||
sizeof(struct sockaddr_in));
|
|
||||||
}
|
|
||||||
unsigned long op;
|
|
||||||
if (addr->ifaddrs.ifa_flags & IFF_BROADCAST) {
|
|
||||||
op = SIOCGIFBRDADDR;
|
|
||||||
} else if (addr->ifaddrs.ifa_flags & IFF_POINTOPOINT) {
|
|
||||||
op = SIOCGIFDSTADDR;
|
|
||||||
} else {
|
|
||||||
op = 0;
|
|
||||||
}
|
|
||||||
if (op && !ioctl(fd, op, ifr)) {
|
|
||||||
memcpy(&addr->bstaddr, &ifr->ifr_addr,
|
|
||||||
sizeof(struct sockaddr_in));
|
|
||||||
addr->ifaddrs.ifa_broadaddr = // is union'd w/ ifu_dstaddr
|
|
||||||
(struct sockaddr *)&addr->bstaddr;
|
|
||||||
}
|
|
||||||
addr->ifaddrs.ifa_next = res;
|
|
||||||
res = (struct ifaddrs *)addr;
|
|
||||||
}
|
}
|
||||||
} else if (family == AF_INET6) {
|
if (!ioctl(fd, SIOCGIFNETMASK, ifr)) {
|
||||||
struct IfAddr6 *addr6;
|
memcpy(&addr->netmask, &ifr->ifr_addr,
|
||||||
if ((addr6 = calloc(1, sizeof(struct IfAddr6)))) {
|
sizeof(struct sockaddr_in));
|
||||||
addr6->ifaddrs.ifa_name = addr6->name;
|
|
||||||
addr6->ifaddrs.ifa_addr = (struct sockaddr *)&addr6->addr;
|
|
||||||
addr6->ifaddrs.ifa_netmask = (struct sockaddr *)&addr6->netmask;
|
|
||||||
addr6->ifaddrs.ifa_broadaddr = (struct sockaddr *)&addr6->bstaddr;
|
|
||||||
addr6->ifaddrs.ifa_data = (void *)&addr6->info;
|
|
||||||
|
|
||||||
memcpy(&addr6->name, &ifr->ifr_name, IFNAMSIZ);
|
|
||||||
addr6->info.addr_flags = ifr->ifr6_flags;
|
|
||||||
addr6->info.addr_scope = ifr->ifr6_scope;
|
|
||||||
|
|
||||||
addr6->addr.sin6_family = AF_INET6;
|
|
||||||
addr6->addr.sin6_port = 0;
|
|
||||||
addr6->addr.sin6_flowinfo = 0;
|
|
||||||
addr6->addr.sin6_scope_id = ifr->ifr6_ifindex;
|
|
||||||
memcpy(&addr6->addr.sin6_addr, &ifr->ifr6_addr,
|
|
||||||
sizeof(struct in6_addr));
|
|
||||||
|
|
||||||
addr6->netmask.sin6_family = AF_INET6;
|
|
||||||
addr6->netmask.sin6_port = 0;
|
|
||||||
addr6->netmask.sin6_flowinfo = 0;
|
|
||||||
addr6->addr.sin6_scope_id = ifr->ifr6_ifindex;
|
|
||||||
memcpy(&addr6->netmask.sin6_addr, &ifr->ifr6_addr,
|
|
||||||
sizeof(struct in6_addr));
|
|
||||||
*((uint128_t *)&(addr6->netmask.sin6_addr)) &=
|
|
||||||
(UINT128_MAX >> ifr->ifr6_prefixlen);
|
|
||||||
|
|
||||||
if (!ioctl(fd, SIOCGIFFLAGS, ifr)) {
|
|
||||||
addr6->ifaddrs.ifa_flags = ifr->ifr_flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
bzero(&addr6->bstaddr, sizeof(struct sockaddr_in6));
|
|
||||||
addr6->ifaddrs.ifa_next = res;
|
|
||||||
res = (struct ifaddrs *)addr6;
|
|
||||||
}
|
}
|
||||||
|
unsigned long op;
|
||||||
|
if (addr->ifaddrs.ifa_flags & IFF_BROADCAST) {
|
||||||
|
op = SIOCGIFBRDADDR;
|
||||||
|
} else if (addr->ifaddrs.ifa_flags & IFF_POINTOPOINT) {
|
||||||
|
op = SIOCGIFDSTADDR;
|
||||||
|
} else {
|
||||||
|
op = 0;
|
||||||
|
}
|
||||||
|
if (op && !ioctl(fd, op, ifr)) {
|
||||||
|
memcpy(&addr->bstaddr, &ifr->ifr_addr,
|
||||||
|
sizeof(struct sockaddr_in));
|
||||||
|
addr->ifaddrs.ifa_broadaddr = // is union'd w/ ifu_dstaddr
|
||||||
|
(struct sockaddr *)&addr->bstaddr;
|
||||||
|
}
|
||||||
|
addr->ifaddrs.ifa_next = res;
|
||||||
|
res = (struct ifaddrs *)addr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*out_ifpp = res;
|
*out_ifpp = res;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_SOCK_STRUCT_IFREQ_H_
|
#ifndef COSMOPOLITAN_LIBC_SOCK_STRUCT_IFREQ_H_
|
||||||
#define COSMOPOLITAN_LIBC_SOCK_STRUCT_IFREQ_H_
|
#define COSMOPOLITAN_LIBC_SOCK_STRUCT_IFREQ_H_
|
||||||
#include "libc/sock/struct/sockaddr.h"
|
#include "libc/sock/struct/sockaddr.h"
|
||||||
#include "libc/sock/struct/sockaddr6.h"
|
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
#define IF_NAMESIZE 16
|
#define IF_NAMESIZE 16
|
||||||
|
@ -12,14 +11,6 @@ struct ifreq {
|
||||||
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */
|
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */
|
||||||
} ifr_ifrn;
|
} ifr_ifrn;
|
||||||
union {
|
union {
|
||||||
struct {
|
|
||||||
uint16_t sa_family;
|
|
||||||
uint16_t ifr6_ifindex; /* Interface index */
|
|
||||||
uint16_t ifr6_flags; /* Flags */
|
|
||||||
uint8_t ifr6_scope; /* Addr scope */
|
|
||||||
uint8_t ifr6_prefixlen; /* Prefix length */
|
|
||||||
struct in6_addr ifr6_addr;
|
|
||||||
} in6;
|
|
||||||
struct sockaddr ifru_addr; /* SIOCGIFADDR */
|
struct sockaddr ifru_addr; /* SIOCGIFADDR */
|
||||||
struct sockaddr ifru_dstaddr; /* SIOCGIFDSTADDR */
|
struct sockaddr ifru_dstaddr; /* SIOCGIFDSTADDR */
|
||||||
struct sockaddr ifru_netmask; /* SIOCGIFNETMASK */
|
struct sockaddr ifru_netmask; /* SIOCGIFNETMASK */
|
||||||
|
@ -38,11 +29,5 @@ struct ifreq {
|
||||||
#define ifr_flags ifr_ifru.ifru_flags /* flags */
|
#define ifr_flags ifr_ifru.ifru_flags /* flags */
|
||||||
#define ifr_ifindex ifr_ifru.ifru_ivalue
|
#define ifr_ifindex ifr_ifru.ifru_ivalue
|
||||||
|
|
||||||
#define ifr6_addr ifr_ifru.in6.ifr6_addr /* IP6 Addr */
|
|
||||||
#define ifr6_scope ifr_ifru.in6.ifr6_scope /* IP6 Addr scope */
|
|
||||||
#define ifr6_prefixlen ifr_ifru.in6.ifr6_prefixlen /* IP6 Prefix length */
|
|
||||||
#define ifr6_ifindex ifr_ifru.in6.ifr6_ifindex /* IP6 If index */
|
|
||||||
#define ifr6_flags ifr_ifru.in6.ifr6_flags /* IP6 If flags */
|
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* COSMOPOLITAN_LIBC_SOCK_STRUCT_IFREQ_H_ */
|
#endif /* COSMOPOLITAN_LIBC_SOCK_STRUCT_IFREQ_H_ */
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/intrin/strace.h"
|
#include "libc/intrin/strace.h"
|
||||||
#include "libc/runtime/syslib.internal.h"
|
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
int sys_getentropy(void *, size_t) asm("sys_getrandom");
|
int sys_getentropy(void *, size_t) asm("sys_getrandom");
|
||||||
|
@ -40,8 +39,6 @@ int getentropy(void *p, size_t n) {
|
||||||
rc = eio();
|
rc = eio();
|
||||||
} else if ((!p && n)) {
|
} else if ((!p && n)) {
|
||||||
rc = efault();
|
rc = efault();
|
||||||
} else if (IsXnuSilicon()) {
|
|
||||||
rc = __syslib->__getentropy(p, n);
|
|
||||||
} else if (IsXnu() || IsOpenbsd()) {
|
} else if (IsXnu() || IsOpenbsd()) {
|
||||||
rc = sys_getentropy(p, n);
|
rc = sys_getentropy(p, n);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1981,4 +1981,4 @@ syscon misc UL_SETFSIZE 2 2 2 2 2 0 0 0
|
||||||
syscon misc XATTR_CREATE 1 1 2 2 0 0 0 0
|
syscon misc XATTR_CREATE 1 1 2 2 0 0 0 0
|
||||||
syscon misc XATTR_REPLACE 2 2 4 4 0 0 0 0
|
syscon misc XATTR_REPLACE 2 2 4 4 0 0 0 0
|
||||||
|
|
||||||
# https://youtu.be/3SNBXoWs4GM
|
# https://youtu.be/GUQUD3IMbb4?t=85
|
||||||
|
|
|
@ -102,8 +102,8 @@ __pid: .quad 0
|
||||||
.previous
|
.previous
|
||||||
|
|
||||||
systemfive_cp:
|
systemfive_cp:
|
||||||
beg
|
push %rbp
|
||||||
pro
|
mov %rsp,%rbp // so backtraces work
|
||||||
systemfive_cancellable: // our pthread_cancel() miracle code
|
systemfive_cancellable: // our pthread_cancel() miracle code
|
||||||
cmpb $0,__tls_enabled(%rip) // inspired by the musl libc design!
|
cmpb $0,__tls_enabled(%rip) // inspired by the musl libc design!
|
||||||
je 1f // we handle linux and bsd together!
|
je 1f // we handle linux and bsd together!
|
||||||
|
@ -123,7 +123,7 @@ systemfive_cancellable: // our pthread_cancel() miracle code
|
||||||
clc // no cancellable system calls exist
|
clc // no cancellable system calls exist
|
||||||
syscall // that have 7+ args on the bsd OSes
|
syscall // that have 7+ args on the bsd OSes
|
||||||
systemfive_cancellable_end: // i/o calls park here for long time
|
systemfive_cancellable_end: // i/o calls park here for long time
|
||||||
epi
|
pop %rbp
|
||||||
jnc 2f
|
jnc 2f
|
||||||
neg %rax // turns bsd errno to system v errno
|
neg %rax // turns bsd errno to system v errno
|
||||||
2: cmp $-4095,%rax // but we still check again on eintr
|
2: cmp $-4095,%rax // but we still check again on eintr
|
||||||
|
@ -144,13 +144,11 @@ systemfive_cancellable_end: // i/o calls park here for long time
|
||||||
je systemfive_errno // we aren't actually cancelled
|
je systemfive_errno // we aren't actually cancelled
|
||||||
jmp 4f // now we are in fact cancelled
|
jmp 4f // now we are in fact cancelled
|
||||||
systemfive_cancel: // SIGTHR will jump here too
|
systemfive_cancel: // SIGTHR will jump here too
|
||||||
epi
|
pop %rbp
|
||||||
4: jmp _pthread_cancel_ack // tail call
|
4: jmp _pthread_cancel_ack // tail call
|
||||||
.weak _pthread_cancel_ack // must be linked if we're cancelled
|
.weak _pthread_cancel_ack // must be linked if we're cancelled
|
||||||
end
|
|
||||||
#if IsModeDbg()
|
#if IsModeDbg()
|
||||||
not_a_cancellation_point: // need BEGIN/END_CANCELLATION_POINT
|
not_a_cancellation_point: // need BEGIN/END_CANCELLATION_POINT
|
||||||
beg
|
|
||||||
nop
|
nop
|
||||||
.weak report_cancellation_point
|
.weak report_cancellation_point
|
||||||
5: ezlea report_cancellation_point,cx
|
5: ezlea report_cancellation_point,cx
|
||||||
|
@ -159,7 +157,6 @@ not_a_cancellation_point: // need BEGIN/END_CANCELLATION_POINT
|
||||||
call *%rcx
|
call *%rcx
|
||||||
6: ud2
|
6: ud2
|
||||||
nop
|
nop
|
||||||
end
|
|
||||||
#endif
|
#endif
|
||||||
.globl systemfive_cancellable_end
|
.globl systemfive_cancellable_end
|
||||||
.globl systemfive_cancellable
|
.globl systemfive_cancellable
|
||||||
|
@ -169,20 +166,19 @@ not_a_cancellation_point: // need BEGIN/END_CANCELLATION_POINT
|
||||||
.Lanchorpoint:
|
.Lanchorpoint:
|
||||||
#if SupportsLinux() || SupportsMetal()
|
#if SupportsLinux() || SupportsMetal()
|
||||||
systemfive_linux:
|
systemfive_linux:
|
||||||
beg
|
|
||||||
and $0xfff,%eax // remove nonlinux bits from ordinal
|
and $0xfff,%eax // remove nonlinux bits from ordinal
|
||||||
cmp $0xfff,%eax // checks if unsupported by platform
|
cmp $0xfff,%eax // checks if unsupported by platform
|
||||||
je systemfive_enosys // never taken branches cost nothing
|
je systemfive_enosys // never taken branches cost nothing
|
||||||
btr $11,%eax // 0x800 means a call is cancellable
|
btr $11,%eax // 0x800 means a call is cancellable
|
||||||
jc systemfive_cp // it is handled by the holiest code
|
jc systemfive_cp // it is handled by the holiest code
|
||||||
mov %rcx,%r10 // syscall instruction clobbers %rcx
|
mov %rcx,%r10 // syscall instruction clobbers %rcx
|
||||||
pro // linux never reads args from stack
|
push %rbp // linux never reads args from stack
|
||||||
|
mov %rsp,%rbp // having frame will help backtraces
|
||||||
syscall // this is known as a context switch
|
syscall // this is known as a context switch
|
||||||
epi // next we check to see if it failed
|
pop %rbp // next we check to see if it failed
|
||||||
cmp $-4095,%rax // system five nexgen32e abi § a.2.1
|
cmp $-4095,%rax // system five nexgen32e abi § a.2.1
|
||||||
jae systemfive_error // encodes errno as neg return value
|
jae systemfive_error // encodes errno as neg return value
|
||||||
ret
|
ret
|
||||||
end
|
|
||||||
.endfn systemfive_linux,globl,hidden
|
.endfn systemfive_linux,globl,hidden
|
||||||
systemfive_error:
|
systemfive_error:
|
||||||
neg %eax
|
neg %eax
|
||||||
|
@ -190,35 +186,27 @@ systemfive_error:
|
||||||
.endfn systemfive_error,globl,hidden
|
.endfn systemfive_error,globl,hidden
|
||||||
#endif
|
#endif
|
||||||
systemfive_errno:
|
systemfive_errno:
|
||||||
beg
|
|
||||||
xchg %eax,%ecx
|
xchg %eax,%ecx
|
||||||
call __errno_location
|
call __errno_location
|
||||||
mov %ecx,(%rax) // normalize to c library convention
|
mov %ecx,(%rax) // normalize to c library convention
|
||||||
push $-1 // negative one is only error result
|
push $-1 // negative one is only error result
|
||||||
pop %rax // the push pop is to save code size
|
pop %rax // the push pop is to save code size
|
||||||
ret
|
ret
|
||||||
end
|
|
||||||
.endfn systemfive_errno,globl,hidden
|
.endfn systemfive_errno,globl,hidden
|
||||||
systemfive_enosys:
|
systemfive_enosys:
|
||||||
beg
|
|
||||||
mov ENOSYS(%rip),%eax
|
mov ENOSYS(%rip),%eax
|
||||||
jmp systemfive_errno
|
jmp systemfive_errno
|
||||||
end
|
|
||||||
.endfn systemfive_enosys,globl,hidden
|
.endfn systemfive_enosys,globl,hidden
|
||||||
#if SupportsNetbsd()
|
#if SupportsNetbsd()
|
||||||
systemfive_netbsd:
|
systemfive_netbsd:
|
||||||
beg
|
|
||||||
shr $4*13,%rax
|
shr $4*13,%rax
|
||||||
jmp systemfive_bsdscrub
|
jmp systemfive_bsdscrub
|
||||||
end
|
|
||||||
.endfn systemfive_netbsd,globl,hidden
|
.endfn systemfive_netbsd,globl,hidden
|
||||||
#endif
|
#endif
|
||||||
#if SupportsOpenbsd()
|
#if SupportsOpenbsd()
|
||||||
systemfive_openbsd:
|
systemfive_openbsd:
|
||||||
beg
|
|
||||||
shr $4*10,%rax
|
shr $4*10,%rax
|
||||||
jmp systemfive_bsdscrub
|
jmp systemfive_bsdscrub
|
||||||
end
|
|
||||||
.endfn systemfive_openbsd,globl,hidden
|
.endfn systemfive_openbsd,globl,hidden
|
||||||
#endif
|
#endif
|
||||||
#if SupportsFreebsd()
|
#if SupportsFreebsd()
|
||||||
|
@ -234,7 +222,6 @@ systemfive_bsdscrub:
|
||||||
// 𝑠𝑙𝑖𝑑𝑒
|
// 𝑠𝑙𝑖𝑑𝑒
|
||||||
.endfn systemfive_bsdscrub,globl,hidden
|
.endfn systemfive_bsdscrub,globl,hidden
|
||||||
systemfive_bsd:
|
systemfive_bsd:
|
||||||
beg
|
|
||||||
cmp $0xfff,%ax
|
cmp $0xfff,%ax
|
||||||
je systemfive_enosys
|
je systemfive_enosys
|
||||||
btr $11,%eax // checks/reset the 800 cancellable bit
|
btr $11,%eax // checks/reset the 800 cancellable bit
|
||||||
|
@ -243,7 +230,6 @@ systemfive_bsd:
|
||||||
syscall // bsd will need arg on stack sometimes
|
syscall // bsd will need arg on stack sometimes
|
||||||
jc systemfive_errno // bsd sets carry flag if %rax is errno
|
jc systemfive_errno // bsd sets carry flag if %rax is errno
|
||||||
ret
|
ret
|
||||||
end
|
|
||||||
.endfn systemfive_bsd
|
.endfn systemfive_bsd
|
||||||
#endif
|
#endif
|
||||||
#if SupportsXnu()
|
#if SupportsXnu()
|
||||||
|
|
|
@ -51,9 +51,6 @@ void SetUpOnce(void) {
|
||||||
// ASSERT_SYS(0, 0, pledge("stdio rpath wpath cpath", 0));
|
// ASSERT_SYS(0, 0, pledge("stdio rpath wpath cpath", 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(jart): fix this test
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
TEST(cachestat, testCachestatOnDevices) {
|
TEST(cachestat, testCachestatOnDevices) {
|
||||||
const char *const files[] = {
|
const char *const files[] = {
|
||||||
"/dev/zero", "/dev/null", "/dev/urandom", "/proc/version", "/proc",
|
"/dev/zero", "/dev/null", "/dev/urandom", "/proc/version", "/proc",
|
||||||
|
@ -67,8 +64,6 @@ TEST(cachestat, testCachestatOnDevices) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TEST(cachestat, testCachestatAfterWrite) {
|
TEST(cachestat, testCachestatAfterWrite) {
|
||||||
size_t size = 4 * pagesize;
|
size_t size = 4 * pagesize;
|
||||||
char *data = gc(xmalloc(size));
|
char *data = gc(xmalloc(size));
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// sh -c '.cosmocc/current/bin/make -j8 V=1 o//test/posix/sigchld_test.runs'
|
// sh -c 'build/bootstrap/make -j8 V=1 o//test/posix/sigchld_test.runs'
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
void Assert(const char *file, int line, bool ok) {
|
void Assert(const char *file, int line, bool ok) {
|
||||||
|
|
|
@ -85,13 +85,6 @@
|
||||||
" executable will self-modify its header on\n" \
|
" executable will self-modify its header on\n" \
|
||||||
" the first run, to use the platform format\n" \
|
" the first run, to use the platform format\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" -k KERNEL test for maching kernel name [repeatable]\n" \
|
|
||||||
" when set, the shell script for subsequent\n" \
|
|
||||||
" loader executables will check if uname -s\n" \
|
|
||||||
" output matches the kernel string, only if\n" \
|
|
||||||
" the loader executable architecture is not\n" \
|
|
||||||
" an architecture in the input binary list\n" \
|
|
||||||
"\n" \
|
|
||||||
" -M PATH bundle ape loader source code file for m1\n" \
|
" -M PATH bundle ape loader source code file for m1\n" \
|
||||||
" processors running the xnu kernel so that\n" \
|
" processors running the xnu kernel so that\n" \
|
||||||
" it can be compiled on the fly by xcode\n" \
|
" it can be compiled on the fly by xcode\n" \
|
||||||
|
@ -220,7 +213,6 @@ struct Loader {
|
||||||
char *ddarg_size1;
|
char *ddarg_size1;
|
||||||
char *ddarg_skip2;
|
char *ddarg_skip2;
|
||||||
char *ddarg_size2;
|
char *ddarg_size2;
|
||||||
const char *kernel;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Loaders {
|
struct Loaders {
|
||||||
|
@ -252,7 +244,6 @@ static struct Inputs inputs;
|
||||||
static char ape_heredoc[15];
|
static char ape_heredoc[15];
|
||||||
static enum Strategy strategy;
|
static enum Strategy strategy;
|
||||||
static struct Loaders loaders;
|
static struct Loaders loaders;
|
||||||
static const char *loader_kernel;
|
|
||||||
static const char *custom_sh_code;
|
static const char *custom_sh_code;
|
||||||
static bool force_bypass_binfmt_misc;
|
static bool force_bypass_binfmt_misc;
|
||||||
static bool generate_debuggable_binary;
|
static bool generate_debuggable_binary;
|
||||||
|
@ -988,19 +979,13 @@ static void AddLoader(const char *path) {
|
||||||
if (loaders.n == ARRAYLEN(loaders.p)) {
|
if (loaders.n == ARRAYLEN(loaders.p)) {
|
||||||
Die(prog, "too many loaders");
|
Die(prog, "too many loaders");
|
||||||
}
|
}
|
||||||
struct Loader *loader = &loaders.p[loaders.n++];
|
loaders.p[loaders.n++].path = path;
|
||||||
loader->path = path;
|
|
||||||
loader->kernel = loader_kernel;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SetLoaderKernel(const char *kernel) {
|
|
||||||
loader_kernel = kernel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetOpts(int argc, char *argv[]) {
|
static void GetOpts(int argc, char *argv[]) {
|
||||||
int opt, bits;
|
int opt, bits;
|
||||||
bool got_support_vector = false;
|
bool got_support_vector = false;
|
||||||
while ((opt = getopt(argc, argv, "hvgsGBo:l:k:S:M:V:")) != -1) {
|
while ((opt = getopt(argc, argv, "hvgsGBo:l:S:M:V:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'o':
|
case 'o':
|
||||||
outpath = optarg;
|
outpath = optarg;
|
||||||
|
@ -1024,10 +1009,6 @@ static void GetOpts(int argc, char *argv[]) {
|
||||||
HashInputString("-l");
|
HashInputString("-l");
|
||||||
AddLoader(optarg);
|
AddLoader(optarg);
|
||||||
break;
|
break;
|
||||||
case 'k':
|
|
||||||
HashInputString("-k");
|
|
||||||
SetLoaderKernel(optarg);
|
|
||||||
break;
|
|
||||||
case 'S':
|
case 'S':
|
||||||
HashInputString("-S");
|
HashInputString("-S");
|
||||||
HashInputString(optarg);
|
HashInputString(optarg);
|
||||||
|
@ -1649,28 +1630,6 @@ static char *GenerateScriptIfMachine(char *p, struct Input *in) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *GenerateScriptIfLoaderMachine(char *p, struct Loader *loader) {
|
|
||||||
if (loader->machine == EM_NEXGEN32E) {
|
|
||||||
p = stpcpy(p, "if [ \"$m\" = x86_64 ] || [ \"$m\" = amd64 ]");
|
|
||||||
} else if (loader->machine == EM_AARCH64) {
|
|
||||||
p = stpcpy(p, "if [ \"$m\" = aarch64 ] || [ \"$m\" = arm64 ] || [ \"$m\" = evbarm ]");
|
|
||||||
} else if (loader->machine == EM_PPC64) {
|
|
||||||
p = stpcpy(p, "if [ \"$m\" = ppc64le ]");
|
|
||||||
} else if (loader->machine == EM_MIPS) {
|
|
||||||
p = stpcpy(p, "if [ \"$m\" = mips64 ]");
|
|
||||||
} else {
|
|
||||||
Die(loader->path, "unsupported cpu architecture");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loader->kernel) {
|
|
||||||
p = stpcpy(p, " && [ \"$k\" = ");
|
|
||||||
p = stpcpy(p, loader->kernel);
|
|
||||||
p = stpcpy(p, " ]");
|
|
||||||
}
|
|
||||||
|
|
||||||
return stpcpy(p, "; then\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *FinishGeneratingDosHeader(char *p) {
|
static char *FinishGeneratingDosHeader(char *p) {
|
||||||
p = WRITE16LE(p, 0x1000); // 10: MZ: lowers upper bound load / 16
|
p = WRITE16LE(p, 0x1000); // 10: MZ: lowers upper bound load / 16
|
||||||
p = WRITE16LE(p, 0xf800); // 12: MZ: roll greed on bss
|
p = WRITE16LE(p, 0xf800); // 12: MZ: roll greed on bss
|
||||||
|
@ -1920,15 +1879,7 @@ int main(int argc, char *argv[]) {
|
||||||
for (j = i + 1; j < loaders.n; ++j) {
|
for (j = i + 1; j < loaders.n; ++j) {
|
||||||
if (loaders.p[i].os == loaders.p[j].os &&
|
if (loaders.p[i].os == loaders.p[j].os &&
|
||||||
loaders.p[i].machine == loaders.p[j].machine) {
|
loaders.p[i].machine == loaders.p[j].machine) {
|
||||||
if (!loaders.p[i].kernel && !loaders.p[j].kernel) {
|
Die(prog, "multiple ape loaders specified for the same platform");
|
||||||
Die(prog, "multiple ape loaders specified for the same platform");
|
|
||||||
}
|
|
||||||
if (loaders.p[i].kernel != NULL &&
|
|
||||||
loaders.p[j].kernel != NULL &&
|
|
||||||
strcmp(loaders.p[i].kernel, loaders.p[j].kernel) == 0) {
|
|
||||||
Die(prog, "multiple ape loaders specified for the same platform "
|
|
||||||
"with matching kernels");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2239,36 +2190,6 @@ int main(int argc, char *argv[]) {
|
||||||
gotsome = true;
|
gotsome = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract the ape loader for non-input architectures
|
|
||||||
// if the user requested a host kernel check, get the host kernel
|
|
||||||
if (loader_kernel) {
|
|
||||||
p = stpcpy(p, "k=$(uname -s 2>/dev/null) || k=unknown\n");
|
|
||||||
}
|
|
||||||
for (i = 0; i < loaders.n; ++i) {
|
|
||||||
struct Loader *loader = loaders.p + i;
|
|
||||||
if (loader->used) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
loader->used = true;
|
|
||||||
p = GenerateScriptIfLoaderMachine(p, loader);
|
|
||||||
p = stpcpy(p, "mkdir -p \"${t%/*}\" ||exit\n"
|
|
||||||
"dd if=\"$o\"");
|
|
||||||
p = stpcpy(p, " skip=");
|
|
||||||
loader->ddarg_skip2 = p;
|
|
||||||
p = GenerateDecimalOffsetRelocation(p);
|
|
||||||
p = stpcpy(p, " count=");
|
|
||||||
loader->ddarg_size2 = p;
|
|
||||||
p = GenerateDecimalOffsetRelocation(p);
|
|
||||||
p = stpcpy(p, " bs=1 2>/dev/null | gzip -dc >\"$t.$$\" ||exit\n"
|
|
||||||
"chmod 755 \"$t.$$\" ||exit\n"
|
|
||||||
"mv -f \"$t.$$\" \"$t\" ||exit\n");
|
|
||||||
p = stpcpy(p, "exec \"$t\" \"$o\" \"$@\"\n"
|
|
||||||
"fi\n");
|
|
||||||
gotsome = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// close if-statements
|
|
||||||
if (inputs.n && (support_vector & _HOSTXNU)) {
|
if (inputs.n && (support_vector & _HOSTXNU)) {
|
||||||
if (!gotsome) {
|
if (!gotsome) {
|
||||||
p = stpcpy(p, "true\n");
|
p = stpcpy(p, "true\n");
|
||||||
|
|
|
@ -1,283 +0,0 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
|
||||||
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
|
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
|
||||||
│ Copyright 2024 Justine Alexandra Roberts Tunney │
|
|
||||||
│ │
|
|
||||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
|
||||||
│ any purpose with or without fee is hereby granted, provided that the │
|
|
||||||
│ above copyright notice and this permission notice appear in all copies. │
|
|
||||||
│ │
|
|
||||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
|
||||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
|
||||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
|
||||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
|
||||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
|
||||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
||||||
#include "libc/calls/calls.h"
|
|
||||||
#include "libc/elf/def.h"
|
|
||||||
#include "libc/elf/elf.h"
|
|
||||||
#include "libc/elf/scalar.h"
|
|
||||||
#include "libc/elf/struct/ehdr.h"
|
|
||||||
#include "libc/elf/struct/phdr.h"
|
|
||||||
#include "libc/intrin/kprintf.h"
|
|
||||||
#include "libc/intrin/likely.h"
|
|
||||||
#include "libc/macros.h"
|
|
||||||
#include "libc/mem/mem.h"
|
|
||||||
#include "libc/runtime/runtime.h"
|
|
||||||
#include "libc/runtime/symbols.internal.h"
|
|
||||||
#include "libc/stdio/stdio.h"
|
|
||||||
#include "libc/str/str.h"
|
|
||||||
#include "libc/sysv/consts/map.h"
|
|
||||||
#include "libc/sysv/consts/o.h"
|
|
||||||
#include "libc/sysv/consts/prot.h"
|
|
||||||
#include "third_party/getopt/getopt.internal.h"
|
|
||||||
|
|
||||||
#define VERSION \
|
|
||||||
"renamestr v0.1\n" \
|
|
||||||
"https://github.com/jart/cosmopolitan\n"
|
|
||||||
|
|
||||||
#define MANUAL \
|
|
||||||
" -f FROM -t TO INPUT \n" \
|
|
||||||
"\n" \
|
|
||||||
"DESCRIPTION\n" \
|
|
||||||
"\n" \
|
|
||||||
" in-place string replacement in ELF binary .rodata\n" \
|
|
||||||
"\n" \
|
|
||||||
" this program may be used to replace strings in the\n" \
|
|
||||||
" .rodata sections of ELF binaries, in-place.\n" \
|
|
||||||
"\n" \
|
|
||||||
"FLAGS\n" \
|
|
||||||
"\n" \
|
|
||||||
" -h show usage\n" \
|
|
||||||
"\n" \
|
|
||||||
" -v show version\n" \
|
|
||||||
"\n" \
|
|
||||||
" -f FROM source string to replace\n" \
|
|
||||||
"\n" \
|
|
||||||
" -t TO target string replacement. must be shorter\n" \
|
|
||||||
" than FROM string for replacement to work\n" \
|
|
||||||
"\n" \
|
|
||||||
" INPUT ELF binary containing strings to replace\n" \
|
|
||||||
"\n"
|
|
||||||
|
|
||||||
static const char *prog;
|
|
||||||
static const char *exepath;
|
|
||||||
static Elf64_Shdr *rodata;
|
|
||||||
static char *rostart;
|
|
||||||
static char *roend;
|
|
||||||
static int exefd;
|
|
||||||
|
|
||||||
static wontreturn void Die(const char *thing, const char *reason) {
|
|
||||||
tinyprint(2, thing, ": ", reason, "\n", NULL);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static wontreturn void DieSys(const char *thing) {
|
|
||||||
perror(thing);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static wontreturn void ShowUsage(int rc, int fd) {
|
|
||||||
tinyprint(fd, "USAGE\n\n ", prog, MANUAL, NULL);
|
|
||||||
exit(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Pwrite(const void *data, size_t size, uint64_t offset) {
|
|
||||||
ssize_t rc;
|
|
||||||
const char *p, *e;
|
|
||||||
for (p = data, e = p + size; p < e; p += (size_t)rc, offset += (size_t)rc) {
|
|
||||||
if ((rc = pwrite(exefd, p, e - p, offset)) == -1) {
|
|
||||||
DieSys(exepath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct String {
|
|
||||||
const char *str;
|
|
||||||
size_t len;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Param {
|
|
||||||
struct String from;
|
|
||||||
struct String to;
|
|
||||||
int count;
|
|
||||||
char *roloc;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Params {
|
|
||||||
int n;
|
|
||||||
struct Param p[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct Params params;
|
|
||||||
|
|
||||||
static void GetOpts(int argc, char *argv[]) {
|
|
||||||
int opt;
|
|
||||||
bool partial = false;
|
|
||||||
params.n = 0;
|
|
||||||
struct Param *param;
|
|
||||||
while ((opt = getopt(argc, argv, "hvf:t:")) != -1) {
|
|
||||||
if (params.n >= ARRAYLEN(params.p)) {
|
|
||||||
param = NULL;
|
|
||||||
} else {
|
|
||||||
param = &(params.p[params.n]);
|
|
||||||
}
|
|
||||||
switch (opt) {
|
|
||||||
case 'f':
|
|
||||||
if (!param) {
|
|
||||||
Die(prog, "too many replacements provided");
|
|
||||||
}
|
|
||||||
if (param->from.str) {
|
|
||||||
Die(prog, "from string already provided");
|
|
||||||
}
|
|
||||||
param->from.str = optarg;
|
|
||||||
param->from.len = strlen(optarg);
|
|
||||||
partial = !partial;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
if (!param) {
|
|
||||||
Die(prog, "too many replacements provided");
|
|
||||||
}
|
|
||||||
if (param->to.str) {
|
|
||||||
Die(prog, "to string already provided");
|
|
||||||
}
|
|
||||||
param->to.str = optarg;
|
|
||||||
param->to.len = strlen(optarg);
|
|
||||||
partial = !partial;
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
tinyprint(0, VERSION, NULL);
|
|
||||||
exit(0);
|
|
||||||
case 'h':
|
|
||||||
ShowUsage(0, 1);
|
|
||||||
default:
|
|
||||||
ShowUsage(1, 2);
|
|
||||||
}
|
|
||||||
if (param->from.str && param->to.str) {
|
|
||||||
if (param->from.len < param->to.len) {
|
|
||||||
Die(prog, "to.str longer than from.str, cannot replace");
|
|
||||||
}
|
|
||||||
params.n++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (params.n == 0) {
|
|
||||||
Die(prog, "no replacements provided");
|
|
||||||
}
|
|
||||||
if (partial) {
|
|
||||||
Die(prog, "partial replacement provided");
|
|
||||||
}
|
|
||||||
if (optind == argc) {
|
|
||||||
Die(prog, "missing input argument");
|
|
||||||
}
|
|
||||||
if (optind != argc - 1) {
|
|
||||||
Die(prog, "too many args");
|
|
||||||
}
|
|
||||||
exepath = argv[optind];
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Input {
|
|
||||||
union {
|
|
||||||
char *map;
|
|
||||||
Elf64_Ehdr *elf;
|
|
||||||
unsigned char *umap;
|
|
||||||
};
|
|
||||||
size_t size;
|
|
||||||
const char *path;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct Input input;
|
|
||||||
|
|
||||||
static void OpenInput(const char *path) {
|
|
||||||
int fd;
|
|
||||||
if ((fd = open(path, O_RDWR)) == -1)
|
|
||||||
DieSys(path);
|
|
||||||
if ((input.size = lseek(fd, 0, SEEK_END)) == -1)
|
|
||||||
DieSys(path);
|
|
||||||
input.path = path;
|
|
||||||
input.map = mmap(0, input.size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
|
||||||
if (input.map == MAP_FAILED)
|
|
||||||
DieSys(path);
|
|
||||||
if (!IsElf64Binary(input.elf, input.size))
|
|
||||||
Die(path, "not an elf64 binary");
|
|
||||||
exefd = fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ReplaceString(struct Param *param) {
|
|
||||||
size_t len;
|
|
||||||
char *x = (char *)memchr(param->roloc, 0, roend - param->roloc);
|
|
||||||
memmove(param->roloc, param->to.str, param->to.len);
|
|
||||||
if (UNLIKELY(x == NULL)) {
|
|
||||||
len = roend - param->roloc;
|
|
||||||
memmove(param->roloc + param->to.len, param->roloc + param->from.len,
|
|
||||||
len - param->from.len);
|
|
||||||
} else {
|
|
||||||
len = x - param->roloc;
|
|
||||||
memmove(param->roloc + param->to.len, param->roloc + param->from.len,
|
|
||||||
len + 1 - param->from.len);
|
|
||||||
}
|
|
||||||
param->roloc += param->to.len;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
#ifdef MODE_DBG
|
|
||||||
ShowCrashReports();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
prog = argv[0];
|
|
||||||
|
|
||||||
if (!prog)
|
|
||||||
prog = "renamestr";
|
|
||||||
|
|
||||||
GetOpts(argc, argv);
|
|
||||||
OpenInput(exepath);
|
|
||||||
rodata = FindElfSectionByName(
|
|
||||||
input.elf, input.size,
|
|
||||||
GetElfSectionNameStringTable(input.elf, input.size), ".rodata");
|
|
||||||
if (!rodata)
|
|
||||||
Die(exepath, "doesn't have .rodata");
|
|
||||||
|
|
||||||
rostart = GetElfSectionAddress(input.elf, input.size, rodata);
|
|
||||||
if (!rostart)
|
|
||||||
Die(prog, "could not get to start of .rodata");
|
|
||||||
roend = rostart + rodata->sh_size;
|
|
||||||
|
|
||||||
#ifdef MODE_DBG
|
|
||||||
kprintf("elf file to process: %s\n", exepath);
|
|
||||||
kprintf("file size is %ld\n", input.size);
|
|
||||||
#endif
|
|
||||||
for (int i = 0; i < params.n; ++i) {
|
|
||||||
struct Param *param = &(params.p[i]);
|
|
||||||
param->roloc = rostart;
|
|
||||||
param->count = 0;
|
|
||||||
#ifdef MODE_DBG
|
|
||||||
kprintf("need to replace '%s' with '%s'\n", param->from.str, param->to.str);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NEXT_ROLOC(z) \
|
|
||||||
memmem((z)->roloc, roend - (z)->roloc, (z)->from.str, (z)->from.len)
|
|
||||||
for (int i = 0; i < params.n; ++i) {
|
|
||||||
struct Param *param = &(params.p[i]);
|
|
||||||
for (param->roloc = NEXT_ROLOC(param); param->roloc != NULL;
|
|
||||||
param->roloc = NEXT_ROLOC(param)) {
|
|
||||||
ReplaceString(param);
|
|
||||||
param->count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#undef NEXT_ROLOC
|
|
||||||
|
|
||||||
Pwrite(input.map, input.size, 0);
|
|
||||||
if (close(exefd)) {
|
|
||||||
Die(prog, "unable to close file after writing");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < params.n; ++i) {
|
|
||||||
struct Param *param = &(params.p[i]);
|
|
||||||
printf("'%s' -> '%s': %d replacements\n", param->from.str, param->to.str,
|
|
||||||
param->count);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
0
tool/cosmocc/bin/cosmoranlib
Executable file → Normal file
0
tool/cosmocc/bin/cosmoranlib
Executable file → Normal file
|
@ -15,49 +15,17 @@ mode() {
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
_nproc() {
|
|
||||||
case $(uname -s) in
|
|
||||||
Darwin) sysctl -n hw.logicalcpu ;;
|
|
||||||
*) nproc ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
TMPDIR=${TMPDIR:-/tmp}
|
|
||||||
OUTDIR=${1:-cosmocc}
|
OUTDIR=${1:-cosmocc}
|
||||||
APELINK=o/$(mode)/tool/build/apelink
|
APELINK=o/$(mode)/tool/build/apelink
|
||||||
AMD64=${2:-x86_64}
|
AMD64=${2:-x86_64}
|
||||||
ARM64=${3:-aarch64}
|
ARM64=${3:-aarch64}
|
||||||
NPROC=$(($(_nproc)/2))
|
NPROC=$(($(nproc)/2))
|
||||||
GCCVER=14.1.0
|
GCCVER=14.1.0
|
||||||
|
|
||||||
if ! MAKE=$(command -v gmake); then
|
make -j$NPROC m= \
|
||||||
if ! MAKE=$(command -v make); then
|
|
||||||
echo please install gnu make >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
$MAKE -j$NPROC m= \
|
|
||||||
$APELINK
|
$APELINK
|
||||||
|
|
||||||
if ! APE=$(command -v ape); then
|
make -j$NPROC m=$AMD64 \
|
||||||
case $(uname -s) in
|
|
||||||
Darwin)
|
|
||||||
case $(mode) in
|
|
||||||
aarch64)
|
|
||||||
cc -O -o "$TMPDIR/ape.$$" .cosmocc/current/bin/ape-m1.c || exit
|
|
||||||
trap 'rm "$TMPDIR/ape.$$"' EXIT
|
|
||||||
APE=$TMPDIR/ape.$$
|
|
||||||
;;
|
|
||||||
*) APE=.cosmocc/current/bin/ape-x86_64.macho ;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
*) APE=.cosmocc/current/bin/ape-$(uname -m).elf ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
stat $APE
|
|
||||||
|
|
||||||
$MAKE -j$NPROC m=$AMD64 \
|
|
||||||
o/cosmocc.h.txt \
|
o/cosmocc.h.txt \
|
||||||
o/$AMD64/ape/ape.lds \
|
o/$AMD64/ape/ape.lds \
|
||||||
o/$AMD64/libc/crt/crt.o \
|
o/$AMD64/libc/crt/crt.o \
|
||||||
|
@ -94,7 +62,7 @@ $MAKE -j$NPROC m=$AMD64 \
|
||||||
o/$AMD64/third_party/make/make.dbg \
|
o/$AMD64/third_party/make/make.dbg \
|
||||||
o/$AMD64/third_party/ctags/ctags.dbg
|
o/$AMD64/third_party/ctags/ctags.dbg
|
||||||
|
|
||||||
$MAKE -j$NPROC m=$AMD64-tiny \
|
make -j$NPROC m=$AMD64-tiny \
|
||||||
o/cosmocc.h.txt \
|
o/cosmocc.h.txt \
|
||||||
o/$AMD64-tiny/ape/ape.lds \
|
o/$AMD64-tiny/ape/ape.lds \
|
||||||
o/$AMD64-tiny/libc/crt/crt.o \
|
o/$AMD64-tiny/libc/crt/crt.o \
|
||||||
|
@ -106,7 +74,7 @@ $MAKE -j$NPROC m=$AMD64-tiny \
|
||||||
o/$AMD64-tiny/cosmopolitan.a \
|
o/$AMD64-tiny/cosmopolitan.a \
|
||||||
o/$AMD64-tiny/third_party/libcxx/libcxx.a \
|
o/$AMD64-tiny/third_party/libcxx/libcxx.a \
|
||||||
|
|
||||||
$MAKE -j$NPROC m=$AMD64-dbg \
|
make -j$NPROC m=$AMD64-dbg \
|
||||||
o/cosmocc.h.txt \
|
o/cosmocc.h.txt \
|
||||||
o/$AMD64-dbg/ape/ape.lds \
|
o/$AMD64-dbg/ape/ape.lds \
|
||||||
o/$AMD64-dbg/libc/crt/crt.o \
|
o/$AMD64-dbg/libc/crt/crt.o \
|
||||||
|
@ -118,7 +86,7 @@ $MAKE -j$NPROC m=$AMD64-dbg \
|
||||||
o/$AMD64-dbg/cosmopolitan.a \
|
o/$AMD64-dbg/cosmopolitan.a \
|
||||||
o/$AMD64-dbg/third_party/libcxx/libcxx.a \
|
o/$AMD64-dbg/third_party/libcxx/libcxx.a \
|
||||||
|
|
||||||
$MAKE CONFIG_TARGET_ARCH= -j$NPROC m=$AMD64-optlinux \
|
make CONFIG_TARGET_ARCH= -j$NPROC m=$AMD64-optlinux \
|
||||||
o/cosmocc.h.txt \
|
o/cosmocc.h.txt \
|
||||||
o/$AMD64-optlinux/ape/ape.lds \
|
o/$AMD64-optlinux/ape/ape.lds \
|
||||||
o/$AMD64-optlinux/libc/crt/crt.o \
|
o/$AMD64-optlinux/libc/crt/crt.o \
|
||||||
|
@ -130,7 +98,7 @@ $MAKE CONFIG_TARGET_ARCH= -j$NPROC m=$AMD64-optlinux \
|
||||||
o/$AMD64-optlinux/cosmopolitan.a \
|
o/$AMD64-optlinux/cosmopolitan.a \
|
||||||
o/$AMD64-optlinux/third_party/libcxx/libcxx.a \
|
o/$AMD64-optlinux/third_party/libcxx/libcxx.a \
|
||||||
|
|
||||||
$MAKE -j$NPROC m=$ARM64 \
|
make -j$NPROC m=$ARM64 \
|
||||||
o/$ARM64/ape/ape.elf \
|
o/$ARM64/ape/ape.elf \
|
||||||
o/$ARM64/ape/aarch64.lds \
|
o/$ARM64/ape/aarch64.lds \
|
||||||
o/$ARM64/libc/crt/crt.o \
|
o/$ARM64/libc/crt/crt.o \
|
||||||
|
@ -162,21 +130,21 @@ $MAKE -j$NPROC m=$ARM64 \
|
||||||
o/$ARM64/third_party/make/make.dbg \
|
o/$ARM64/third_party/make/make.dbg \
|
||||||
o/$ARM64/third_party/ctags/ctags.dbg
|
o/$ARM64/third_party/ctags/ctags.dbg
|
||||||
|
|
||||||
$MAKE -j$NPROC m=$ARM64-tiny \
|
make -j$NPROC m=$ARM64-tiny \
|
||||||
o/$ARM64-tiny/ape/ape.elf \
|
o/$ARM64-tiny/ape/ape.elf \
|
||||||
o/$ARM64-tiny/ape/aarch64.lds \
|
o/$ARM64-tiny/ape/aarch64.lds \
|
||||||
o/$ARM64-tiny/libc/crt/crt.o \
|
o/$ARM64-tiny/libc/crt/crt.o \
|
||||||
o/$ARM64-tiny/cosmopolitan.a \
|
o/$ARM64-tiny/cosmopolitan.a \
|
||||||
o/$ARM64-tiny/third_party/libcxx/libcxx.a \
|
o/$ARM64-tiny/third_party/libcxx/libcxx.a \
|
||||||
|
|
||||||
$MAKE -j$NPROC m=$ARM64-dbg \
|
make -j$NPROC m=$ARM64-dbg \
|
||||||
o/$ARM64-dbg/ape/ape.elf \
|
o/$ARM64-dbg/ape/ape.elf \
|
||||||
o/$ARM64-dbg/ape/aarch64.lds \
|
o/$ARM64-dbg/ape/aarch64.lds \
|
||||||
o/$ARM64-dbg/libc/crt/crt.o \
|
o/$ARM64-dbg/libc/crt/crt.o \
|
||||||
o/$ARM64-dbg/cosmopolitan.a \
|
o/$ARM64-dbg/cosmopolitan.a \
|
||||||
o/$ARM64-dbg/third_party/libcxx/libcxx.a \
|
o/$ARM64-dbg/third_party/libcxx/libcxx.a \
|
||||||
|
|
||||||
$MAKE -j$NPROC m=$ARM64-optlinux \
|
make -j$NPROC m=$ARM64-optlinux \
|
||||||
o/$ARM64-optlinux/ape/ape.elf \
|
o/$ARM64-optlinux/ape/ape.elf \
|
||||||
o/$ARM64-optlinux/ape/aarch64.lds \
|
o/$ARM64-optlinux/ape/aarch64.lds \
|
||||||
o/$ARM64-optlinux/libc/crt/crt.o \
|
o/$ARM64-optlinux/libc/crt/crt.o \
|
||||||
|
@ -201,36 +169,14 @@ fetch() {
|
||||||
else
|
else
|
||||||
curl -LO $1
|
curl -LO $1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if command -v sha256sum >/dev/null 2>&1; then
|
|
||||||
# can use system sha256sum
|
|
||||||
true
|
|
||||||
elif command -v shasum >/dev/null 2>&1; then
|
|
||||||
sha256sum() {
|
|
||||||
shasum -a 256 "$@"
|
|
||||||
}
|
|
||||||
elif command -v "$PWD/o/build/sha256sum" >/dev/null 2>&1; then
|
|
||||||
# should have been built by download-cosmocc.sh if a system
|
|
||||||
# sha256sum/shasum does not exist
|
|
||||||
sha256sum() {
|
|
||||||
"$PWD/o/build/sha256sum" "$@"
|
|
||||||
}
|
|
||||||
else
|
|
||||||
echo please install sha256sum >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
filename=$(basename $1)
|
|
||||||
printf '%s\n' "$2 $filename" >$filename.sha256sum
|
|
||||||
sha256sum -c $filename.sha256sum || exit 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OLD=$PWD
|
OLD=$PWD
|
||||||
cd "$OUTDIR/"
|
cd "$OUTDIR/"
|
||||||
if [ ! -x bin/x86_64-linux-cosmo-gcc ]; then
|
if [ ! -x bin/x86_64-linux-cosmo-gcc ]; then
|
||||||
fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.60/aarch64-gcc.zip 6a07f915ec0296cd33b3142e75c00ed1a7072c75d92c82a0c0b5f5df2cff0dd2 &
|
fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.60/aarch64-gcc.zip &
|
||||||
fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.60/x86_64-gcc.zip cbb1659c56a0a4f95a71f59f94693515000d3dd53f79a597acacd53cbad2c7d8 &
|
fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.60/x86_64-gcc.zip &
|
||||||
fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.60/llvm.zip d42c2e46204d4332975d2d7464c5df63c898c34f8d9d2b83c168c14705ca8edd &
|
fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.60/llvm.zip &
|
||||||
wait
|
wait
|
||||||
unzip aarch64-gcc.zip &
|
unzip aarch64-gcc.zip &
|
||||||
unzip x86_64-gcc.zip &
|
unzip x86_64-gcc.zip &
|
||||||
|
@ -326,7 +272,7 @@ cp -f o/$ARM64/ape/ape.elf "$OUTDIR/bin/ape-aarch64.elf"
|
||||||
for x in assimilate march-native mktemper fixupobj zipcopy apelink pecheck mkdeps zipobj \
|
for x in assimilate march-native mktemper fixupobj zipcopy apelink pecheck mkdeps zipobj \
|
||||||
ar chmod cocmd cp echo gzip objbincopy package rm touch mkdir compile sha256sum \
|
ar chmod cocmd cp echo gzip objbincopy package rm touch mkdir compile sha256sum \
|
||||||
resymbol; do
|
resymbol; do
|
||||||
$APE $APELINK \
|
ape $APELINK \
|
||||||
-l o/$AMD64/ape/ape.elf \
|
-l o/$AMD64/ape/ape.elf \
|
||||||
-l o/$ARM64/ape/ape.elf \
|
-l o/$ARM64/ape/ape.elf \
|
||||||
-M ape/ape-m1.c \
|
-M ape/ape-m1.c \
|
||||||
|
@ -340,7 +286,7 @@ for x in ar chmod cp echo gzip package rm touch mkdir compile sha256sum; do
|
||||||
done
|
done
|
||||||
|
|
||||||
for x in make ctags; do
|
for x in make ctags; do
|
||||||
$APE $APELINK \
|
ape $APELINK \
|
||||||
-l o/$AMD64/ape/ape.elf \
|
-l o/$AMD64/ape/ape.elf \
|
||||||
-l o/$ARM64/ape/ape.elf \
|
-l o/$ARM64/ape/ape.elf \
|
||||||
-M ape/ape-m1.c \
|
-M ape/ape-m1.c \
|
||||||
|
|
|
@ -4864,9 +4864,9 @@ UNIX MODULE
|
||||||
end
|
end
|
||||||
|
|
||||||
It's possible to accomplish the same thing as unix.mapshared()
|
It's possible to accomplish the same thing as unix.mapshared()
|
||||||
using files and unix.fcntl() advisory locks. For example, that's
|
using files and unix.fcntl() advisory locks. However this goes
|
||||||
what SQLite does and we recommend using SQLite for IPC in redbean.
|
significantly faster. For example, that's what SQLite does and
|
||||||
However, unix.mapshared is significantly faster and if your app
|
we recommend using SQLite for IPC in redbean. But, if your app
|
||||||
has thousands of forked processes fighting for a file lock you
|
has thousands of forked processes fighting for a file lock you
|
||||||
might need something lower level than file locks, to implement
|
might need something lower level than file locks, to implement
|
||||||
things like throttling. Shared memory is a good way to do that
|
things like throttling. Shared memory is a good way to do that
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
eth0
|
eth0
|
||||||
addr: 10.10.10.237
|
addr: 10.10.10.237
|
||||||
netmask: 255.255.255.0
|
netmask: 255.255.255.0
|
||||||
broadcast: 10.10.10.255
|
broadcast: 255.255.255.0
|
||||||
flags: IFF_UP IFF_BROADCAST IFF_MULTICAST IFF_RUNNING
|
flags: IFF_UP IFF_BROADCAST IFF_MULTICAST IFF_RUNNING
|
||||||
|
|
||||||
lo
|
lo
|
||||||
|
@ -74,87 +74,13 @@ int main(int argc, char *argv[]) {
|
||||||
tinyprint(1, "netmask: ", buf, "\n", NULL);
|
tinyprint(1, "netmask: ", buf, "\n", NULL);
|
||||||
}
|
}
|
||||||
if ((ifa->ifa_flags & IFF_BROADCAST) &&
|
if ((ifa->ifa_flags & IFF_BROADCAST) &&
|
||||||
sockaddr2str(ifa->ifa_broadaddr, buf, sizeof(buf))) {
|
sockaddr2str(ifa->ifa_netmask, buf, sizeof(buf))) {
|
||||||
tinyprint(1, "broadcast: ", buf, "\n", NULL);
|
tinyprint(1, "broadcast: ", buf, "\n", NULL);
|
||||||
} else if ((ifa->ifa_flags & IFF_POINTOPOINT) &&
|
} else if ((ifa->ifa_flags & IFF_POINTOPOINT) &&
|
||||||
sockaddr2str(ifa->ifa_dstaddr, buf, sizeof(buf))) {
|
sockaddr2str(ifa->ifa_dstaddr, buf, sizeof(buf))) {
|
||||||
tinyprint(1, "dstaddr: ", buf, "\n", NULL);
|
tinyprint(1, "dstaddr: ", buf, "\n", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ifa->ifa_addr->sa_family == AF_INET6) {
|
|
||||||
int scope = ((int *)ifa->ifa_data)[0];
|
|
||||||
int aflags = ((int *)ifa->ifa_data)[1];
|
|
||||||
// #define IPV6_ADDR_LOOPBACK 0x0010U
|
|
||||||
// #define IPV6_ADDR_LINKLOCAL 0x0020U
|
|
||||||
// #define IPV6_ADDR_SITELOCAL 0x0040U
|
|
||||||
|
|
||||||
// #define IFA_F_TEMPORARY 0x01
|
|
||||||
// #define IFA_F_NODAD 0x02
|
|
||||||
// #define IFA_F_OPTIMISTIC 0x04
|
|
||||||
// #define IFA_F_DADFAILED 0x08
|
|
||||||
// #define IFA_F_HOMEADDRESS 0x10
|
|
||||||
// #define IFA_F_DEPRECATED 0x20
|
|
||||||
// #define IFA_F_TENTATIVE 0x40
|
|
||||||
// #define IFA_F_PERMANENT 0x80
|
|
||||||
// #define IFA_F_MANAGETEMPADDR 0x100
|
|
||||||
// #define IFA_F_NOPREFIXROUTE 0x200
|
|
||||||
// #define IFA_F_MCAUTOJOIN 0x400
|
|
||||||
// #define IFA_F_STABLE_PRIVACY 0x800
|
|
||||||
tinyprint(1, "scope:", NULL);
|
|
||||||
if (scope == 0x10) {
|
|
||||||
tinyprint(1, " loopback", NULL);
|
|
||||||
}
|
|
||||||
if (scope == 0x20) {
|
|
||||||
tinyprint(1, " linklocal", NULL);
|
|
||||||
}
|
|
||||||
if (scope == 0x40) {
|
|
||||||
tinyprint(1, " sitelocal", NULL);
|
|
||||||
}
|
|
||||||
if (scope == 0x00) {
|
|
||||||
tinyprint(1, " global", NULL);
|
|
||||||
}
|
|
||||||
tinyprint(1, "\n", NULL);
|
|
||||||
|
|
||||||
tinyprint(1, "addr flags:", NULL);
|
|
||||||
if (aflags & 0x01) {
|
|
||||||
tinyprint(1, " temporary", NULL);
|
|
||||||
}
|
|
||||||
if (aflags & 0x02) {
|
|
||||||
tinyprint(1, " nodad", NULL);
|
|
||||||
}
|
|
||||||
if (aflags & 0x04) {
|
|
||||||
tinyprint(1, " optimistic", NULL);
|
|
||||||
}
|
|
||||||
if (aflags & 0x08) {
|
|
||||||
tinyprint(1, " dadfailed", NULL);
|
|
||||||
}
|
|
||||||
if (aflags & 0x10) {
|
|
||||||
tinyprint(1, " homeaddress", NULL);
|
|
||||||
}
|
|
||||||
if (aflags & 0x20) {
|
|
||||||
tinyprint(1, " deprecated", NULL);
|
|
||||||
}
|
|
||||||
if (aflags & 0x40) {
|
|
||||||
tinyprint(1, " tentative", NULL);
|
|
||||||
}
|
|
||||||
if (aflags & 0x80) {
|
|
||||||
tinyprint(1, " permanent", NULL);
|
|
||||||
}
|
|
||||||
if (aflags & 0x100) {
|
|
||||||
tinyprint(1, " managetempaddr", NULL);
|
|
||||||
}
|
|
||||||
if (aflags & 0x200) {
|
|
||||||
tinyprint(1, " noprefixroute", NULL);
|
|
||||||
}
|
|
||||||
if (aflags & 0x400) {
|
|
||||||
tinyprint(1, " mcautojoin", NULL);
|
|
||||||
}
|
|
||||||
if (aflags & 0x800) {
|
|
||||||
tinyprint(1, " stable_privacy", NULL);
|
|
||||||
}
|
|
||||||
tinyprint(1, "\n", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
tinyprint(1, "flags:", NULL);
|
tinyprint(1, "flags:", NULL);
|
||||||
if (ifa->ifa_flags & IFF_UP) {
|
if (ifa->ifa_flags & IFF_UP) {
|
||||||
tinyprint(1, " IFF_UP", NULL);
|
tinyprint(1, " IFF_UP", NULL);
|
||||||
|
|
|
@ -17,12 +17,7 @@ cut -d' ' -f2 /proc/mounts | while read -r line; do
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
if whence doas >/dev/null; then
|
|
||||||
doas=doas
|
|
||||||
else
|
|
||||||
doas=sudo
|
|
||||||
fi
|
|
||||||
( set -x
|
( set -x
|
||||||
$doas mount -t tmpfs -o size=10G,noatime,nodiratime /dev/shm "$o"
|
sudo mount -t tmpfs -o size=10G,noatime,nodiratime /dev/shm "$o"
|
||||||
)
|
)
|
||||||
# vim:ft=zsh
|
# vim:ft=zsh
|
||||||
|
|
|
@ -38,21 +38,8 @@ done
|
||||||
whence nproc >/dev/null || autoload -Uz nproc
|
whence nproc >/dev/null || autoload -Uz nproc
|
||||||
j=-j$(nproc)
|
j=-j$(nproc)
|
||||||
}
|
}
|
||||||
local make=$(
|
local make=${MAKE:-${COSMOCC:-/opt/cosmocc/current}/bin/make}
|
||||||
case $MAKE in
|
[[ -x $make ]] || make=${COSMO:-$PWD}/build/bootstrap/make
|
||||||
*/*) echo $MAKE ;;
|
|
||||||
?*) command -v $MAKE ;;
|
|
||||||
*) echo .cosmocc/current/bin/make ;;
|
|
||||||
esac
|
|
||||||
)
|
|
||||||
if [[ ! -x $make ]]; then
|
|
||||||
{ echo 'please install a suitable make, for example:'
|
|
||||||
echo
|
|
||||||
echo 'https://cosmo.zip/pub/cosmos/bin/make'
|
|
||||||
echo
|
|
||||||
echo 'then put it on $PATH or point $MAKE to it.'
|
|
||||||
} >&2; return 1
|
|
||||||
fi
|
|
||||||
( set -x
|
( set -x
|
||||||
exec $make $j $flags MODE=$mode $targs )
|
exec $make $j $flags MODE=$mode $targs )
|
||||||
# vim:ft=zsh
|
# vim:ft=zsh
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL
|
|
||||||
MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl
|
|
||||||
eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT
|
|
||||||
JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx
|
|
||||||
MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
|
|
||||||
Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg
|
|
||||||
VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm
|
|
||||||
aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo
|
|
||||||
I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng
|
|
||||||
o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G
|
|
||||||
A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD
|
|
||||||
VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB
|
|
||||||
zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW
|
|
||||||
RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
|
|
||||||
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
|
|
||||||
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
|
|
||||||
BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
|
|
||||||
MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
|
|
||||||
BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
|
|
||||||
aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
|
|
||||||
dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
|
|
||||||
AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
|
|
||||||
3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
|
|
||||||
tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
|
|
||||||
Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
|
|
||||||
VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
|
|
||||||
79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
|
|
||||||
c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
|
|
||||||
Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
|
|
||||||
c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
|
|
||||||
UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
|
|
||||||
Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
|
|
||||||
BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
|
|
||||||
A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
|
|
||||||
Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
|
|
||||||
VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
|
|
||||||
ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
|
|
||||||
8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
|
|
||||||
iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
|
|
||||||
Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
|
|
||||||
XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
|
|
||||||
qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
|
|
||||||
VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
|
|
||||||
L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
|
|
||||||
jjxDah2nGN59PRbxYvnKkKj9
|
|
||||||
-----END CERTIFICATE-----
|
|
Loading…
Add table
Add a link
Reference in a new issue