Get us closer to building busybox

This change undefines __linux__ and adds APIs like clock_settime(). The
gosh darned getopt_long() API has been reintroduced, thanks to OpenBSD.
This commit is contained in:
Justine Tunney 2023-06-18 04:02:01 -07:00
parent 5ac522f0de
commit 0409096658
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
52 changed files with 914 additions and 37 deletions

View file

@ -131,7 +131,6 @@ include ape/ape.mk # │
include libc/fmt/fmt.mk # │
include libc/vga/vga.mk #─┘
include libc/calls/calls.mk #─┐
include third_party/getopt/getopt.mk # │
include libc/runtime/runtime.mk # ├──SYSTEMS RUNTIME
include libc/crt/crt.mk # │ You can issue system calls
include tool/hello/hello.mk # │
@ -148,6 +147,7 @@ include third_party/libcxx/libcxx.mk # │
include net/net.mk # │
include third_party/vqsort/vqsort.mk # │
include libc/log/log.mk # │
include third_party/getopt/getopt.mk # │
include third_party/ggml/ggml.mk # │
include third_party/radpajama/radpajama.mk # │
include third_party/bzip2/bzip2.mk # │

View file

@ -91,3 +91,17 @@ int cfsetispeed(struct termios *t, uint32_t speed) {
return 0;
}
}
/**
* Sets input and output baud rate.
*
* @param speed can be `B0`, `B50`, `B38400`, `B4000000`, etc.
* @return 0 on success, or -1 w/ errno
* @raise EINVAL if `speed` isn't valid
* @asyncsignalsafe
*/
int cfsetspeed(struct termios *t, uint32_t speed) {
if (cfsetispeed(t, speed) == -1) return -1;
if (cfsetospeed(t, speed) == -1) return -1;
return 0;
}

View file

@ -0,0 +1,53 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2023 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/asan.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timespec.internal.h"
#include "libc/calls/struct/timeval.h"
#include "libc/calls/struct/timeval.internal.h"
#include "libc/dce.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/errfuns.h"
/**
* Changes time.
*/
int clock_settime(int clockid, const struct timespec *ts) {
int rc;
struct timeval tv;
if (clockid == 127) {
rc = einval(); // 127 is used by consts.sh to mean unsupported
} else if (!ts || (IsAsan() && !__asan_is_valid_timespec(ts))) {
rc = efault();
} else if (IsXnu()) {
if (clockid == CLOCK_REALTIME) {
tv = timespec_totimeval(*ts);
rc = sys_settimeofday(&tv, 0);
} else {
rc = einval();
}
} else {
rc = sys_clock_settime(clockid, ts);
}
STRACE("clock_settime(%s, %s) → %d% m", DescribeClockName(clockid),
DescribeTimespec(0, ts), rc);
return rc;
}

39
libc/calls/settimeofday.c Normal file
View file

@ -0,0 +1,39 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2023 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/asan.internal.h"
#include "libc/calls/struct/timeval.h"
#include "libc/calls/struct/timeval.internal.h"
#include "libc/dce.h"
#include "libc/intrin/strace.internal.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/struct/timezone.h"
/**
* Changes time.
*/
int settimeofday(const struct timeval *tv, const struct timezone *tz) {
int rc;
if (!tv || (IsAsan() && !__asan_is_valid_timeval(tv))) {
rc = efault();
} else {
rc = sys_settimeofday(tv, 0);
}
STRACE("settimeofday(%s, %p) → %d% m", DescribeTimeval(0, tv), tz, rc);
return rc;
}

View file

@ -10,6 +10,7 @@ struct timespec {
int clock_getres(int, struct timespec *);
int clock_gettime(int, struct timespec *);
int clock_settime(int, const struct timespec *);
int clock_nanosleep(int, int, const struct timespec *, struct timespec *);
int futimens(int, const struct timespec[2]);
int nanosleep(const struct timespec *, struct timespec *);

View file

@ -10,6 +10,7 @@ int __sys_clock_nanosleep(int, int, const struct timespec *, struct timespec *)
int __sys_utimensat(int, const char *, const struct timespec[2], int) _Hide;
int __utimens(int, const char *, const struct timespec[2], int) _Hide;
int sys_clock_getres(int, struct timespec *) _Hide;
int sys_clock_settime(int, const struct timespec *);
int sys_clock_gettime(int, struct timespec *) _Hide;
int sys_clock_gettime_nt(int, struct timespec *) _Hide;
int sys_clock_gettime_m1(int, struct timespec *) _Hide;

View file

@ -13,6 +13,7 @@ struct timeval {
int futimes(int, const struct timeval[2]);
int futimesat(int, const char *, const struct timeval[2]);
int gettimeofday(struct timeval *, struct timezone *);
int settimeofday(const struct timeval *, const struct timezone *);
int lutimes(const char *, const struct timeval[2]);
int utimes(const char *, const struct timeval[2]);

View file

@ -7,6 +7,7 @@
COSMOPOLITAN_C_START_
axdx_t sys_gettimeofday(struct timeval *, struct timezone *, void *) _Hide;
int sys_settimeofday(const struct timeval *, const struct timezone *) _Hide;
int sys_futimes(int, const struct timeval *) _Hide;
int sys_lutimes(const char *, const struct timeval *) _Hide;
int sys_utimes(const char *, const struct timeval *) _Hide;

View file

@ -29,8 +29,9 @@ int tcflow(int, int);
int tcflush(int, int);
int tcsendbreak(int, int);
void cfmakeraw(struct termios *);
int cfsetospeed(struct termios *, unsigned);
int cfsetispeed(struct termios *, unsigned);
int cfsetspeed(struct termios *, uint32_t);
int cfsetospeed(struct termios *, uint32_t);
int cfsetispeed(struct termios *, uint32_t);
uint32_t cfgetospeed(const struct termios *);
uint32_t cfgetispeed(const struct termios *);
int tcsetwinsize(int, const struct winsize *);

View file

@ -86,9 +86,10 @@ libcesque nosideeffect;
cosmopolitan § conversion » manipulation
*/
#ifdef COSMO
char *dirname(char *);
char *basename(char *);
#ifdef COSMO
char *stripext(char *);
char *stripexts(char *);
#endif

View file

@ -62,6 +62,14 @@
#undef linux
#endif
#ifdef __linux
#undef __linux
#endif
#ifdef __linux__
#undef __linux__
#endif
#ifndef __BIGGEST_ALIGNMENT__
#define __BIGGEST_ALIGNMENT__ 16
#endif

View file

@ -1,4 +1,5 @@
#ifndef _GETOPT_H
#define _GETOPT_H
#include "third_party/getopt/getopt.h"
#include "third_party/getopt/long.h"
#endif /* _GETOPT_H */

View file

@ -1,4 +1,5 @@
#ifndef _LIBGEN_H
#define _LIBGEN_H
#include "libc/fmt/conv.h"
#endif /* _LIBGEN_H */

View file

@ -0,0 +1,5 @@
#ifndef _NET_ETHERNET_H
#define _NET_ETHERNET_H
#include "libc/sock/struct/ether_header.h"
#include "libc/sysv/consts/ethernet.h"
#endif /* _NET_ETHERNET_H */

View file

@ -0,0 +1,6 @@
#ifndef _NET_IF_ARP_H
#define _NET_IF_ARP_H
#include "libc/sock/struct/arphdr.h"
#include "libc/sock/struct/arpreq.h"
#include "libc/sysv/consts/arp.h"
#endif /* _NET_IF_ARP_H */

View file

@ -1,5 +1,22 @@
#ifndef _NETDB_H
#define _NETDB_H
#include "libc/calls/weirdtypes.h"
#include "libc/dns/dns.h"
#include "libc/dns/ent.h"
#include "libc/sock/sock.h"
#include "libc/sock/struct/in6_pktinfo.h"
#include "libc/sock/struct/in_pktinfo.h"
#include "libc/sock/struct/ip_mreq.h"
#include "libc/sock/struct/sockaddr.h"
#include "libc/sock/struct/sockaddr6.h"
#include "libc/sysv/consts/in.h"
#include "libc/sysv/consts/inaddr.h"
#include "libc/sysv/consts/inet6.h"
#include "libc/sysv/consts/ip.h"
#include "libc/sysv/consts/ipport.h"
#include "libc/sysv/consts/ipproto.h"
#include "libc/sysv/consts/ipv6.h"
#include "libc/sysv/consts/mcast.h"
#include "libc/sysv/consts/pf.h"
#include "libc/sysv/consts/sock.h"
#endif /* _NETDB_H */

View file

@ -2,6 +2,8 @@
#define COSMOPOLITAN_LIBC_ISYSTEM_NETINET_IN_H_
#include "libc/calls/weirdtypes.h"
#include "libc/sock/sock.h"
#include "libc/sock/struct/in6_pktinfo.h"
#include "libc/sock/struct/in_pktinfo.h"
#include "libc/sock/struct/ip_mreq.h"
#include "libc/sock/struct/sockaddr.h"
#include "libc/sock/struct/sockaddr6.h"

View file

@ -5,6 +5,7 @@
#include "libc/fmt/conv.h"
#include "libc/limits.h"
#include "libc/mem/alg.h"
#include "libc/mem/alloca.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/dprintf.h"

View file

@ -5,6 +5,7 @@
#include "libc/calls/struct/winsize.h"
#include "libc/sysv/consts/fd.h"
#include "libc/sysv/consts/fio.h"
#include "libc/sysv/consts/io.h"
#include "libc/sysv/consts/modem.h"
#include "libc/sysv/consts/pty.h"
#include "libc/sysv/consts/sio.h"

24
libc/mem/mallopt.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2023 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/mem/mem.h"
#include "third_party/dlmalloc/dlmalloc.h"
int mallopt(int param_number, int value) {
return dlmallopt(param_number, value);
}

View file

@ -28,6 +28,7 @@ void *aligned_alloc(size_t, size_t) attributeallocalign((1))
int posix_memalign(void **, size_t, size_t);
bool __grow(void *, size_t *, size_t, size_t) paramsnonnull((1, 2)) libcesque;
int mallopt(int, int);
int malloc_trim(size_t);
size_t bulk_free(void **, size_t);
size_t malloc_usable_size(void *);

16
libc/sock/struct/arphdr.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef COSMOPOLITAN_LIBC_SOCK_STRUCT_ARPHDR_H_
#define COSMOPOLITAN_LIBC_SOCK_STRUCT_ARPHDR_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct arphdr {
uint16_t ar_hrd;
uint16_t ar_pro;
uint8_t ar_hln;
uint8_t ar_pln;
uint16_t ar_op;
};
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_SOCK_STRUCT_ARPHDR_H_ */

17
libc/sock/struct/arpreq.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef COSMOPOLITAN_LIBC_SOCK_STRUCT_ARPREQ_H_
#define COSMOPOLITAN_LIBC_SOCK_STRUCT_ARPREQ_H_
#include "libc/sock/struct/sockaddr.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct arpreq {
struct sockaddr arp_pa;
struct sockaddr arp_ha;
int arp_flags;
struct sockaddr arp_netmask;
char arp_dev[16];
};
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_SOCK_STRUCT_ARPREQ_H_ */

View file

@ -0,0 +1,21 @@
#ifndef COSMOPOLITAN_LIBC_SOCK_STRUCT_ETHER_HEADER_H_
#define COSMOPOLITAN_LIBC_SOCK_STRUCT_ETHER_HEADER_H_
#define ETH_ALEN 6
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct ether_addr {
uint8_t ether_addr_octet[ETH_ALEN];
};
struct ether_header {
uint8_t ether_dhost[ETH_ALEN];
uint8_t ether_shost[ETH_ALEN];
uint16_t ether_type;
};
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_SOCK_STRUCT_ETHER_HEADER_H_ */

View file

@ -0,0 +1,14 @@
#ifndef COSMOPOLITAN_LIBC_SOCK_STRUCT_IN6_PKTINFO_H_
#define COSMOPOLITAN_LIBC_SOCK_STRUCT_IN6_PKTINFO_H_
#include "libc/sock/struct/sockaddr6.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct in6_pktinfo {
struct in6_addr ipi6_addr;
unsigned ipi6_ifindex;
};
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_SOCK_STRUCT_IN6_PKTINFO_H_ */

View file

@ -0,0 +1,15 @@
#ifndef COSMOPOLITAN_LIBC_SOCK_STRUCT_IN_PKTINFO_H_
#define COSMOPOLITAN_LIBC_SOCK_STRUCT_IN_PKTINFO_H_
#include "libc/sock/struct/sockaddr.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct in_pktinfo {
int ipi_ifindex;
struct in_addr ipi_spec_dst;
struct in_addr ipi_addr;
};
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_SOCK_STRUCT_IN_PKTINFO_H_ */

View file

@ -33,7 +33,7 @@
#endif
#if defined(__cplusplus) && __cplusplus >= 201103L
#include <type_traits>
#include "third_party/libcxx/type_traits"
#define __ckd_is_unsigned(res) std::is_unsigned<decltype(*(res))>::value
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define __ckd_is_unsigned(res) \

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_clock_settime,0x1ac0580e9ffff0e3,112,4095,globl
.scall sys_clock_settime,0x1ac0580e9ffff0e3,112,4095,globl,hidden

6
libc/sysv/consts/arp.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_ARP_H_
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_ARP_H_
#define ARPHRD_ETHER 1
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_ARP_H_ */

View file

@ -0,0 +1,32 @@
#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_ETHERNET_H_
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_ETHERNET_H_
#define ETHERTYPE_PUP 0x0200
#define ETHERTYPE_SPRITE 0x0500
#define ETHERTYPE_IP 0x0800
#define ETHERTYPE_ARP 0x0806
#define ETHERTYPE_REVARP 0x8035
#define ETHERTYPE_AT 0x809B
#define ETHERTYPE_AARP 0x80F3
#define ETHERTYPE_VLAN 0x8100
#define ETHERTYPE_IPX 0x8137
#define ETHERTYPE_IPV6 0x86dd
#define ETHERTYPE_LOOPBACK 0x9000
#define ETHER_ADDR_LEN ETH_ALEN
#define ETHER_TYPE_LEN 2
#define ETHER_CRC_LEN 4
#define ETHER_HDR_LEN ETH_HLEN
#define ETHER_MIN_LEN (ETH_ZLEN + ETHER_CRC_LEN)
#define ETHER_MAX_LEN (ETH_FRAME_LEN + ETHER_CRC_LEN)
#define ETHER_IS_VALID_LEN(foo) \
((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
#define ETHERTYPE_TRAIL 0x1000
#define ETHERTYPE_NTRAILER 16
#define ETHERMTU ETH_DATA_LEN
#define ETHERMIN (ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_ETHERNET_H_ */

18
libc/sysv/consts/io.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_IO_H_
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_IO_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define _IOC(a, b, c, d) (((a) << 30) | ((b) << 8) | (c) | ((d) << 16))
#define _IOC_NONE 0U
#define _IOC_WRITE 1U
#define _IOC_READ 2U
#define _IO(a, b) _IOC(_IOC_NONE, (a), (b), 0)
#define _IOW(a, b, c) _IOC(_IOC_WRITE, (a), (b), sizeof(c))
#define _IOR(a, b, c) _IOC(_IOC_READ, (a), (b), sizeof(c))
#define _IOWR(a, b, c) _IOC(_IOC_READ | _IOC_WRITE, (a), (b), sizeof(c))
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_IO_H_ */

View file

@ -250,7 +250,7 @@ scall sys_ktimer_delete 0xffffff0ecfffffff 0xfff globl # no wrapper
scall sys_ktimer_getoverrun 0xffffff0effffffff 0xfff globl # no wrapper
scall sys_ktimer_gettime 0xffffff0eefffffff 0xfff globl # no wrapper
scall sys_ktimer_settime 0xffffff0edfffffff 0xfff globl # no wrapper
scall sys_clock_settime 0x1ac0580e9ffff0e3 0x070 globl # no wrapper
scall sys_clock_settime 0x1ac0580e9ffff0e3 0x070 globl hidden # no wrapper
scall sys_clock_gettime 0x1ab0570e8ffff0e4 0x071 globl hidden # Linux 2.6+ (c. 2003); XNU uses magic address
scall sys_clock_getres 0x1ad0590eaffff0e5 0x072 globl hidden
scall sys_mbind 0xfffffffffffff0ed 0x0eb globl # no wrapper; numa numa yeah

View file

@ -1022,10 +1022,6 @@ __unix\000\
1\000\
__unix__\000\
1\000\
__linux\000\
1\000\
__linux__\000\
1\000\
__gnu_linux__\000\
1\000\
__BYTE_ORDER__\000\

View file

@ -46,7 +46,7 @@
#define CONST_SECTION .section .rodata
#if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
defined(__linux__)
defined(__linux__) || defined(__COSMOPOLITAN__)
#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits
#else
#define NO_EXEC_STACK_DIRECTIVE

Binary file not shown.

Binary file not shown.

View file

@ -19,6 +19,7 @@ libexec/gcc/$ARCH-linux-musl/$NEWVERSION/collect2
libexec/gcc/$ARCH-linux-musl/$NEWVERSION/cc1
libexec/gcc/$ARCH-linux-musl/$NEWVERSION/cc1plus
bin/$ARCH-linux-musl-as
bin/$ARCH-linux-musl-ar
bin/$ARCH-linux-musl-gcc
bin/$ARCH-linux-musl-g++
bin/$ARCH-linux-musl-nm

View file

@ -18,6 +18,7 @@ THIRD_PARTY_GETOPT_A_CHECKS = \
THIRD_PARTY_GETOPT_A_DIRECTDEPS = \
LIBC_CALLS \
LIBC_INTRIN \
LIBC_LOG \
LIBC_NEXGEN32E \
LIBC_STR

513
third_party/getopt/long.c vendored Normal file
View file

@ -0,0 +1,513 @@
#include "third_party/getopt/long.h"
#include "libc/log/bsd.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
// clang-format off
/* $OpenBSD: getopt_long.c,v 1.32 2020/05/27 22:25:09 schwarze Exp $ */
/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
/*
* Copyright (c) 2002 Todd C. Miller <millert@openbsd.org>
*
* Permission to use, copy, modify, and 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.
*
* Sponsored in part by the Defense Advanced Research Projects
* Agency (DARPA) and Air Force Research Laboratory, Air Force
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
*/
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron and Thomas Klausner.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
int opterr = 1; /* if error message should be printed */
int optind = 1; /* index into parent argv vector */
int optopt = '?'; /* character checked for validity */
int optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#if 0
/* DEF_* only work on initialized (non-COMMON) variables */
DEF_WEAK(opterr);
DEF_WEAK(optind);
DEF_WEAK(optopt);
#endif
#define PRINT_ERROR ((opterr) && (*options != ':'))
#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
/* return values */
#define BADCH (int)'?'
#define BADARG ((*options == ':') ? (int)':' : (int)'?')
#define INORDER (int)1
#define EMSG ""
static int getopt_internal(int, char * const *, const char *,
const struct option *, int *, int);
static int parse_long_options(char * const *, const char *,
const struct option *, int *, int, int);
static int gcd(int, int);
static void permute_args(int, int, int, char * const *);
static char *place = EMSG; /* option letter processing */
/* XXX: set optreset to 1 rather than these two */
static int nonopt_start = -1; /* first non option argument (for permute) */
static int nonopt_end = -1; /* first option after non options (for permute) */
/* Error messages */
static const char recargchar[] = "option requires an argument -- %c";
static const char recargstring[] = "option requires an argument -- %s";
static const char ambig[] = "ambiguous option -- %.*s";
static const char noarg[] = "option doesn't take an argument -- %.*s";
static const char illoptchar[] = "unknown option -- %c";
static const char illoptstring[] = "unknown option -- %s";
/*
* Compute the greatest common divisor of a and b.
*/
static int
gcd(int a, int b)
{
int c;
c = a % b;
while (c != 0) {
a = b;
b = c;
c = a % b;
}
return (b);
}
/*
* Exchange the block from nonopt_start to nonopt_end with the block
* from nonopt_end to opt_end (keeping the same order of arguments
* in each block).
*/
static void
permute_args(int panonopt_start, int panonopt_end, int opt_end,
char * const *nargv)
{
int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
char *swap;
/*
* compute lengths of blocks and number and size of cycles
*/
nnonopts = panonopt_end - panonopt_start;
nopts = opt_end - panonopt_end;
ncycle = gcd(nnonopts, nopts);
cyclelen = (opt_end - panonopt_start) / ncycle;
for (i = 0; i < ncycle; i++) {
cstart = panonopt_end+i;
pos = cstart;
for (j = 0; j < cyclelen; j++) {
if (pos >= panonopt_end)
pos -= nnonopts;
else
pos += nopts;
swap = nargv[pos];
((char **)nargv)[pos] = nargv[cstart];
((char **)nargv)[cstart] = swap;
}
}
}
/*
* parse_long_options --
* Parse long options in argc/argv argument vector.
* Returns -1 if short_too is set and the option does not match long_options.
*/
static int
parse_long_options(char * const *nargv, const char *options,
const struct option *long_options, int *idx, int short_too, int flags)
{
char *current_argv, *has_equal;
size_t current_argv_len;
int i, match, exact_match, second_partial_match;
current_argv = place;
match = -1;
exact_match = 0;
second_partial_match = 0;
optind++;
if ((has_equal = strchr(current_argv, '=')) != NULL) {
/* argument found (--option=arg) */
current_argv_len = has_equal - current_argv;
has_equal++;
} else
current_argv_len = strlen(current_argv);
for (i = 0; long_options[i].name; i++) {
/* find matching long option */
if (strncmp(current_argv, long_options[i].name,
current_argv_len))
continue;
if (strlen(long_options[i].name) == current_argv_len) {
/* exact match */
match = i;
exact_match = 1;
break;
}
/*
* If this is a known short option, don't allow
* a partial match of a single character.
*/
if (short_too && current_argv_len == 1)
continue;
if (match == -1) /* first partial match */
match = i;
else if ((flags & FLAG_LONGONLY) ||
long_options[i].has_arg != long_options[match].has_arg ||
long_options[i].flag != long_options[match].flag ||
long_options[i].val != long_options[match].val)
second_partial_match = 1;
}
if (!exact_match && second_partial_match) {
/* ambiguous abbreviation */
if (PRINT_ERROR)
warnx(ambig, (int)current_argv_len, current_argv);
optopt = 0;
return (BADCH);
}
if (match != -1) { /* option found */
if (long_options[match].has_arg == no_argument
&& has_equal) {
if (PRINT_ERROR)
warnx(noarg, (int)current_argv_len,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
return (BADARG);
}
if (long_options[match].has_arg == required_argument ||
long_options[match].has_arg == optional_argument) {
if (has_equal)
optarg = has_equal;
else if (long_options[match].has_arg ==
required_argument) {
/*
* optional argument doesn't use next nargv
*/
optarg = nargv[optind++];
}
}
if ((long_options[match].has_arg == required_argument)
&& (optarg == NULL)) {
/*
* Missing argument; leading ':' indicates no error
* should be generated.
*/
if (PRINT_ERROR)
warnx(recargstring,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
--optind;
return (BADARG);
}
} else { /* unknown option */
if (short_too) {
--optind;
return (-1);
}
if (PRINT_ERROR)
warnx(illoptstring, current_argv);
optopt = 0;
return (BADCH);
}
if (idx)
*idx = match;
if (long_options[match].flag) {
*long_options[match].flag = long_options[match].val;
return (0);
} else
return (long_options[match].val);
}
/*
* getopt_internal --
* Parse argc/argv argument vector. Called by user level routines.
*/
static int
getopt_internal(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx, int flags)
{
char *oli; /* option letter list index */
int optchar, short_too;
static int posixly_correct = -1;
if (options == NULL)
return (-1);
/*
* XXX Some GNU programs (like cvs) set optind to 0 instead of
* XXX using optreset. Work around this braindamage.
*/
if (optind == 0)
optind = optreset = 1;
/*
* Disable GNU extensions if POSIXLY_CORRECT is set or options
* string begins with a '+'.
*/
if (posixly_correct == -1 || optreset)
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
if (*options == '-')
flags |= FLAG_ALLARGS;
else if (posixly_correct || *options == '+')
flags &= ~FLAG_PERMUTE;
if (*options == '+' || *options == '-')
options++;
optarg = NULL;
if (optreset)
nonopt_start = nonopt_end = -1;
start:
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc) { /* end of argument vector */
place = EMSG;
if (nonopt_end != -1) {
/* do permutation, if we have to */
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
else if (nonopt_start != -1) {
/*
* If we skipped non-options, set optind
* to the first of them.
*/
optind = nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
if (*(place = nargv[optind]) != '-' ||
(place[1] == '\0' && strchr(options, '-') == NULL)) {
place = EMSG; /* found non-option */
if (flags & FLAG_ALLARGS) {
/*
* GNU extension:
* return non-option as argument to option 1
*/
optarg = nargv[optind++];
return (INORDER);
}
if (!(flags & FLAG_PERMUTE)) {
/*
* If no permutation wanted, stop parsing
* at first non-option.
*/
return (-1);
}
/* do permutation */
if (nonopt_start == -1)
nonopt_start = optind;
else if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
nonopt_start = optind -
(nonopt_end - nonopt_start);
nonopt_end = -1;
}
optind++;
/* process next argument */
goto start;
}
if (nonopt_start != -1 && nonopt_end == -1)
nonopt_end = optind;
/*
* If we have "-" do nothing, if "--" we are done.
*/
if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
optind++;
place = EMSG;
/*
* We found an option (--), so if we skipped
* non-options, we have to permute.
*/
if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
}
/*
* Check long options if:
* 1) we were passed some
* 2) the arg is not just "-"
* 3) either the arg starts with -- we are getopt_long_only()
*/
if (long_options != NULL && place != nargv[optind] &&
(*place == '-' || (flags & FLAG_LONGONLY))) {
short_too = 0;
if (*place == '-')
place++; /* --foo long option */
else if (*place != ':' && strchr(options, *place) != NULL)
short_too = 1; /* could be short option too */
optchar = parse_long_options(nargv, options, long_options,
idx, short_too, flags);
if (optchar != -1) {
place = EMSG;
return (optchar);
}
}
if ((optchar = (int)*place++) == (int)':' ||
(oli = strchr(options, optchar)) == NULL) {
if (!*place)
++optind;
if (PRINT_ERROR)
warnx(illoptchar, optchar);
optopt = optchar;
return (BADCH);
}
if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
/* -W long-option */
if (*place) /* no space */
/* NOTHING */;
else if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else /* white space */
place = nargv[optind];
optchar = parse_long_options(nargv, options, long_options,
idx, 0, flags);
place = EMSG;
return (optchar);
}
if (*++oli != ':') { /* doesn't take argument */
if (!*place)
++optind;
} else { /* takes (optional) argument */
optarg = NULL;
if (*place) /* no white space */
optarg = place;
else if (oli[1] != ':') { /* arg not optional */
if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else
optarg = nargv[optind];
}
place = EMSG;
++optind;
}
/* dump back option letter */
return (optchar);
}
/*
* getopt --
* Parse argc/argv argument vector.
*/
int
getopt(int nargc, char * const *nargv, const char *options)
{
/*
* We don't pass FLAG_PERMUTE to getopt_internal() since
* the BSD getopt(3) (unlike GNU) has never done this.
*
* Furthermore, since many privileged programs call getopt()
* before dropping privileges it makes sense to keep things
* as simple (and bug-free) as possible.
*/
return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
}
/*
* getopt_long --
* Parse argc/argv argument vector.
*/
int
getopt_long(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE));
}
/*
* getopt_long_only --
* Parse argc/argv argument vector.
*/
int
getopt_long_only(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE|FLAG_LONGONLY));
}

24
third_party/getopt/long.h vendored Normal file
View file

@ -0,0 +1,24 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_GETOPT_LONG_H_
#define COSMOPOLITAN_THIRD_PARTY_GETOPT_LONG_H_
#define no_argument 0
#define required_argument 1
#define optional_argument 2
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
int getopt_long(int, char *const *, const char *, const struct option *, int *);
int getopt_long_only(int, char *const *, const char *, const struct option *,
int *);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_GETOPT_LONG_H_ */

View file

@ -165,7 +165,7 @@ struct llama_mmap {
size = file->size;
int fd = fileno(file->fp);
int flags = MAP_SHARED;
#ifdef __linux__
#if defined(__linux__) || defined(__COSMOPOLITAN__)
flags |= MAP_POPULATE;
#endif
addr = mmap(NULL, file->size, PROT_READ, flags, fd, 0);

View file

@ -292,6 +292,9 @@
# define _LIBCPP_HAS_QUICK_EXIT
# define _LIBCPP_HAS_TIMESPEC_GET
# define _LIBCPP_HAS_C11_FEATURES
# elif defined(__COSMOPOLITAN__)
# define _LIBCPP_HAS_TIMESPEC_GET
# define _LIBCPP_HAS_C11_FEATURES
# elif defined(__linux__)
# if !defined(_LIBCPP_HAS_MUSL_LIBC)
# if _LIBCPP_GLIBC_PREREQ(2, 15) || defined(__BIONIC__)
@ -1039,6 +1042,7 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
defined(__APPLE__) || \
defined(__CloudABI__) || \
defined(__sun__) || \
defined(__COSMOPOLITAN__) || \
(defined(__MINGW32__) && __has_include(<pthread.h>))
# define _LIBCPP_HAS_THREAD_API_PTHREAD
# elif defined(_LIBCPP_WIN32API)

View file

@ -25,7 +25,8 @@
// No _LIBCPP_ELAST needed on Fuchsia
#elif defined(__wasi__)
// No _LIBCPP_ELAST needed on WASI
#elif defined(__linux__) || defined(_LIBCPP_HAS_MUSL_LIBC)
#elif defined(__linux__) || defined(_LIBCPP_HAS_MUSL_LIBC) || \
defined(__COSMOPOLITAN__)
#define _LIBCPP_ELAST 4095
#elif defined(__APPLE__)
// No _LIBCPP_ELAST needed on Apple

View file

@ -20,7 +20,7 @@
// No _LIBCPP_ELAST needed on Fuchsia
#elif defined(__wasi__)
// No _LIBCPP_ELAST needed on WASI
#elif defined(__linux__) || defined(_LIBCPP_HAS_MUSL_LIBC)
#elif defined(__linux__) || defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__COSMOPOLITAN__)
#define _LIBCPP_ELAST 4095
#elif defined(__APPLE__)
// No _LIBCPP_ELAST needed on Apple

View file

@ -274,7 +274,7 @@ static const JSMallocFunctions trace_mf = {
(size_t (*)(const void *))_msize,
#elif defined(EMSCRIPTEN)
NULL,
#elif defined(__linux__)
#elif defined(__linux__) || defined(__COSMOPOLITAN__)
(size_t (*)(const void *))malloc_usable_size,
#else
/* change this to `NULL,` if compilation fails */

View file

@ -1045,7 +1045,7 @@ static JSValue js_std_file_tell(JSContext *ctx, JSValueConst this_val,
int64_t pos;
if (!f)
return JS_EXCEPTION;
#if defined(__linux__)
#if defined(__linux__) || defined(__COSMOPOLITAN__)
pos = ftello(f);
#else
pos = ftell(f);
@ -1068,7 +1068,7 @@ static JSValue js_std_file_seek(JSContext *ctx, JSValueConst this_val,
return JS_EXCEPTION;
if (JS_ToInt32(ctx, &whence, argv[1]))
return JS_EXCEPTION;
#if defined(__linux__)
#if defined(__linux__) || defined(__COSMOPOLITAN__)
ret = fseeko(f, pos, whence);
#else
ret = fseek(f, pos, whence);
@ -1938,7 +1938,7 @@ static JSValue js_os_signal(JSContext *ctx, JSValueConst this_val,
return JS_UNDEFINED;
}
#if defined(__linux__) || defined(__APPLE__)
#if defined(__linux__) || defined(__APPLE__) || defined(__COSMOPOLITAN__)
static int64_t get_time_ms(void)
{
struct timespec ts;

View file

@ -567,7 +567,7 @@ static const JSMallocFunctions def_malloc_funcs = {
(size_t (*)(const void *))_msize,
#elif defined(EMSCRIPTEN)
NULL,
#elif defined(__linux__)
#elif defined(__linux__) || defined(__COSMOPOLITAN__)
(size_t (*)(const void *))malloc_usable_size,
#else
/* change this to `NULL,` if compilation fails */

View file

@ -183,7 +183,7 @@ struct gptneox_mmap {
size = file->size;
int fd = fileno(file->fp);
int flags = MAP_SHARED;
#ifdef __linux__
#if defined(__linux__) || defined(__COSMOPOLITAN__)
flags |= MAP_POPULATE;
#endif
addr = mmap(NULL, file->size, PROT_READ, flags, fd, 0);

View file

@ -998,7 +998,8 @@ typedef INT16_TYPE LogEst;
|| (defined(__APPLE__) && defined(__MACH__)) \
|| defined(__sun) \
|| defined(__FreeBSD__) \
|| defined(__DragonFly__)
|| defined(__DragonFly__) \
|| defined(__COSMOPOLITAN__)
# define SQLITE_MAX_MMAP_SIZE 0x7fff0000 /* 2147418112 */
# else
# define SQLITE_MAX_MMAP_SIZE 0

View file

@ -244,8 +244,16 @@ static void OptimizePatchableFunctionEntries(void) {
if (!(p = GetElfSectionAddress(elf, esize, shdr))) {
Die("elf header overflow");
}
p += syms[i].st_value - shdr->sh_addr;
pe = p + syms[i].st_size;
if (syms[i].st_value < shdr->sh_addr) {
Die("elf symbol beneath section");
}
if ((syms[i].st_value - shdr->sh_addr > esize ||
(p += syms[i].st_value - shdr->sh_addr) >=
(unsigned char *)elf + esize) ||
(syms[i].st_size >= esize ||
(pe = p + syms[i].st_size) >= (unsigned char *)elf + esize)) {
Die("elf symbol overflow");
};
for (; p + 1 < pe; p += n) {
if (p[0] != 0x90) break;
if (p[1] != 0x90) break;

View file

@ -72,7 +72,8 @@ PREDEF="-include libc/integral/normalize.inc"
CCFLAGS="-fdata-sections -ffunction-sections -fno-pie -mno-tls-direct-seg-refs -mno-red-zone -fportcosmo"
CXXFLAGS="-fno-exceptions -fuse-cxa-atexit -fno-threadsafe-statics"
CPPFLAGS="-nostdinc -iquote $COSMO -isystem $COSMOS/include -isystem $COSMO/libc/isystem"
LDFLAGS="-static -no-pie -nostdlib -fuse-ld=bfd -Wl,-melf_x86_64 -Wl,--gc-sections -L$COSMOS/lib -Wl,-T,$COSMO/o/$MODE/ape/public/ape.lds $COSMO/o/$MODE/ape/ape-no-modify-self.o $COSMO/o/$MODE/libc/crt/crt.o"
LDFLAGS="-static -no-pie -nostdlib -fuse-ld=bfd -Wl,-melf_x86_64"
APEFLAGS="-L$COSMOS/lib -Wl,--gc-sections -Wl,-T,$COSMO/o/$MODE/ape/public/ape.lds $COSMO/o/$MODE/ape/ape-no-modify-self.o $COSMO/o/$MODE/libc/crt/crt.o"
LDLIBS="$COSMO/o/$MODE/third_party/libcxx/libcxx.a $COSMO/o/$MODE/cosmopolitan.a"
CXX="$COSMO/o/third_party/gcc/bin/x86_64-linux-musl-g++"
@ -115,6 +116,7 @@ FIRST=1
OUTPUT=
INTENT=ld
NEED_OUTPUT=
RELOCATABLE=0
FRAME=-fno-omit-frame-pointer
for x; do
if [ $FIRST -eq 1 ]; then
@ -133,6 +135,8 @@ for x; do
OPT=$x
elif [ x"$x" = x"-c" ]; then
INTENT=cc
elif [ x"$x" = x"-r" ]; then
RELOCATABLE=1
elif [ x"$x" = x"-E" ]; then
INTENT=cpp
elif [ x"$x" = x"-o" ]; then
@ -156,6 +160,10 @@ for x; do
set -- "$@" "$x"
done
if [ $RELOCATABLE -eq 0 ]; then
APEFLAGS=
fi
if [ x"$MODE" = x"nox87" ]; then
CCFLAGS="$CCFLAGS -mlong-double-64"
fi
@ -170,14 +178,15 @@ if [ $INTENT = cpp ]; then
elif [ $INTENT = cc ]; then
set -- $PLATFORM $PREDEF $CCFLAGS $CXXFLAGS $CPPFLAGS "$@" $FRAME
else
set -- $PLATFORM $PREDEF $LDFLAGS $CXXFLAGS $CPPFLAGS "$@" $LDLIBS -Wl,-z,common-page-size=4096 -Wl,-z,max-page-size=4096 $FRAME
set -- $PLATFORM $PREDEF $LDFLAGS $APEFLAGS $CXXFLAGS $CPPFLAGS "$@" \
$LDLIBS -Wl,-z,common-page-size=4096 -Wl,-z,max-page-size=4096 $FRAME
fi
set -- "$CXX" "$@"
printf '(cd %s; %s)\n' "$PWD" "$*" >>/tmp/build.log
"$@" || exit
if [ -n "$OUTPUT" ]; then
if [ -n "$OUTPUT" ] && [ -f "$OUTPUT" ]; then
if [ $INTENT = cc ] || [ $INTENT = ld ]; then
"$FIXUPOBJ" "$OUTPUT" || exit
fi
@ -190,14 +199,6 @@ if [ -n "$OUTPUT" ]; then
mv -f "$OUTPUT" "$OUTPUT.dbg" || exit
"$OBJCOPY" -S -O binary "$OUTPUT.dbg" "$OUTPUT" || exit
"$ZIPCOPY" "$OUTPUT.dbg" "$OUTPUT" || exit
else
# cosmocc -o foo ...
# -> foo (elf)
# -> foo.com (ape)
# -> foo.com.dbg (elf)
cp -f "$OUTPUT" "$OUTPUT.com.dbg" || exit
"$OBJCOPY" -S -O binary "$OUTPUT" "$OUTPUT.com" || exit
"$ZIPCOPY" "$OUTPUT" "$OUTPUT.com" || exit
fi
fi
fi

View file

@ -72,7 +72,8 @@ PREDEF="-include libc/integral/normalize.inc"
CCFLAGS="-fdata-sections -ffunction-sections -fno-pie -mno-tls-direct-seg-refs -mno-red-zone -fportcosmo"
CFLAGS=
CPPFLAGS="-nostdinc -iquote $COSMO -isystem $COSMOS/include -isystem $COSMO/libc/isystem"
LDFLAGS="-static -no-pie -nostdlib -fuse-ld=bfd -Wl,-melf_x86_64 -Wl,--gc-sections -L$COSMOS/lib -Wl,-T,$COSMO/o/$MODE/ape/public/ape.lds $COSMO/o/$MODE/ape/ape-no-modify-self.o $COSMO/o/$MODE/libc/crt/crt.o"
LDFLAGS="-static -no-pie -nostdlib -fuse-ld=bfd -Wl,-melf_x86_64"
APEFLAGS="-L$COSMOS/lib -Wl,--gc-sections -Wl,-T,$COSMO/o/$MODE/ape/public/ape.lds $COSMO/o/$MODE/ape/ape-no-modify-self.o $COSMO/o/$MODE/libc/crt/crt.o"
LDLIBS="$COSMO/o/$MODE/cosmopolitan.a"
CC="$COSMO/o/third_party/gcc/bin/x86_64-linux-musl-gcc"
@ -115,6 +116,7 @@ FIRST=1
OUTPUT=
INTENT=ld
NEED_OUTPUT=
RELOCATABLE=0
FRAME=-fno-omit-frame-pointer
for x; do
if [ $FIRST -eq 1 ]; then
@ -133,6 +135,8 @@ for x; do
OPT=$x
elif [ x"$x" = x"-c" ]; then
INTENT=cc
elif [ x"$x" = x"-r" ]; then
RELOCATABLE=1
elif [ x"$x" = x"-E" ]; then
INTENT=cpp
elif [ x"$x" = x"-o" ]; then
@ -156,6 +160,10 @@ for x; do
set -- "$@" "$x"
done
if [ $RELOCATABLE -eq 1 ]; then
APEFLAGS=
fi
if [ x"$MODE" = x"nox87" ]; then
CCFLAGS="$CCFLAGS -mlong-double-64"
fi
@ -170,7 +178,8 @@ if [ $INTENT = cpp ]; then
elif [ $INTENT = cc ]; then
set -- $PLATFORM $PREDEF $CCFLAGS $CFLAGS $CPPFLAGS "$@" $FRAME
else
set -- $PLATFORM $PREDEF $LDFLAGS $CFLAGS $CPPFLAGS "$@" $LDLIBS -Wl,-z,common-page-size=4096 -Wl,-z,max-page-size=4096 $FRAME
set -- $PLATFORM $PREDEF $LDFLAGS $APEFLAGS $CFLAGS $CPPFLAGS "$@" \
$LDLIBS -Wl,-z,common-page-size=4096 -Wl,-z,max-page-size=4096 $FRAME
fi
set -- "$CC" "$@"