Fix breakages in Linux-only build modes

- compile.com now polyfills -march=native which gcc/clang removed
- Guarantee zero Windows code is linked into non-Windows binaries
- MODE=tinylinux binaries are now back to being as tiny as ~4kb
- Improve the runtime's stack allocation / alignment hack
- GitHub Actions now tests Linux modes for assurance
This commit is contained in:
Justine Tunney 2023-07-09 19:47:46 -07:00
parent 0e4c828a8e
commit 3dc86ce154
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
32 changed files with 283 additions and 104 deletions

View file

@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
mode: ["", tiny, rel]
mode: ["", tiny, rel, tinylinux, optlinux]
steps:
- uses: actions/checkout@v3

View file

@ -275,6 +275,7 @@ SECTIONS {
}
ape_stack_memsz = DEFINED(ape_stack_memsz) ? ape_stack_memsz : APE_STACKSIZE;
ape_stack_memsz2 = ape_stack_memsz * 2;
_tls_size = _tbss_end - _tdata_start;
_tdata_size = _tdata_end - _tdata_start;
_tbss_size = _tbss_end - _tbss_start;

View file

@ -794,7 +794,7 @@ ape_loader_end:
.stub ape_stack_vaddr,quad // is mmap()'d with MAP_FIXED
.stub ape_stack_paddr,quad // ignored
.stub ape_stack_filesz,quad // ignored
.stub ape_stack_memsz,quad // is mmap(size) argument
.stub ape_stack_memsz2,quad // is mmap(size) argument
.stub ape_stack_align,quad // must be 16+
#if SupportsOpenbsd() || SupportsNetbsd()
@ -1718,7 +1718,7 @@ ape_grub_entry:
αcτµαlly pδrταblε εxεcµταblε § cosmopolitan libc runtime runtime
*/
kernel: movabs $ape_stack_vaddr,%rsp
add $ape_stack_memsz,%rsp
add $ape_stack_memsz2,%rsp
movl $0,0x7b000 // unmap null 2mb
#if USE_SYMBOL_HACK
.byte 0x0f,0x1f,0207 // nop rdi binbase

View file

@ -317,7 +317,6 @@ SECTIONS {
__privileged_start = .;
*(.privileged)
__privileged_end = .;
. += . > 0 ? CODE_GRANULE : 0;
KEEP(*(.ape.pad.text))
. = ALIGN(CONSTANT(COMMONPAGESIZE));
@ -344,9 +343,11 @@ SECTIONS {
/*BEGIN: read-only data that's only needed for initialization */
#if SupportsWindows()
/* Windows DLL Import Directory */
KEEP(*(.idata.ro));
KEEP(*(SORT_BY_NAME(.idata.ro.*)))
#endif
. = ALIGN(__SIZEOF_POINTER__);
__init_array_start = .;
@ -405,7 +406,9 @@ SECTIONS {
.data . : {
/*BEGIN: Read/Write Data */
#if SupportsWindows()
KEEP(*(SORT_BY_NAME(.piro.data.sort.iat.*)))
#endif
/*BEGIN: NT FORK COPYING */
KEEP(*(.dataprologue))
*(.data .data.*)
@ -517,6 +520,11 @@ SECTIONS {
}
/DISCARD/ : {
#if !SupportsWindows()
*(.idata.ro);
*(.idata.ro.*)
*(.piro.data.sort.iat.*)
#endif
*(__patchable_function_entries)
*(__mcount_loc)
*(.discard)
@ -569,6 +577,7 @@ ape_stack_vaddr = DEFINED(ape_stack_vaddr) ? ape_stack_vaddr : 0x700000000000;
ape_stack_paddr = ape_ram_paddr + ape_ram_filesz;
ape_stack_filesz = 0;
ape_stack_memsz = DEFINED(ape_stack_memsz) ? ape_stack_memsz : APE_STACKSIZE;
ape_stack_memsz2 = ape_stack_memsz * 2;
ape_stack_align = 16;
ape_note_offset = ape_cod_offset + (ape_note - ape_cod_vaddr);

Binary file not shown.

View file

@ -76,12 +76,13 @@ endif
ifeq ($(MODE), opt)
ENABLE_FTRACE = 1
CONFIG_OFLAGS ?= -g
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG -msse2avx -Wa,-msse2avx
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG
CONFIG_CCFLAGS += $(BACKTRACES) -O3 -fmerge-all-constants
TARGET_ARCH ?= -march=skylake
TARGET_ARCH ?= -march=native
endif
# Optimized Linux Mode
# The Fastest Mode of All
#
# - `make MODE=optlinux`
# - Turns on red zone
@ -91,8 +92,9 @@ endif
# - Turns off support for other operating systems
#
ifeq ($(MODE), optlinux)
ENABLE_FTRACE = 1
CONFIG_OFLAGS ?= -g
CONFIG_CPPFLAGS += -DNDEBUG -msse2avx -Wa,-msse2avx -DSUPPORT_VECTOR=1
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG -DSUPPORT_VECTOR=1
CONFIG_CCFLAGS += -O3 -fmerge-all-constants
CONFIG_COPTS += -mred-zone
TARGET_ARCH ?= -march=native
@ -114,7 +116,7 @@ endif
# - CHECK_xx() won't leak strings into binary
#
ifeq ($(MODE), rel)
CONFIG_CPPFLAGS += -DNDEBUG
CONFIG_CPPFLAGS += -DNDEBUG -DDWARFLESS
CONFIG_CCFLAGS += $(BACKTRACES) -O2
TARGET_ARCH ?= -msse3
PYFLAGS += -O1

View file

@ -55,8 +55,10 @@ static errno_t sys_clock_nanosleep(int clock, int flags,
rc = sys_clock_nanosleep_xnu(clock, flags, req, rem);
} else if (IsOpenbsd()) {
rc = sys_clock_nanosleep_openbsd(clock, flags, req, rem);
} else {
} else if (IsWindows()) {
rc = sys_clock_nanosleep_nt(clock, flags, req, rem);
} else {
rc = enosys();
}
if (rc == -1) {
rc = errno;

View file

@ -25,6 +25,7 @@
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/limits.h"
#include "libc/sysv/errfuns.h"
/**
* Returns nice value of thing.
@ -72,8 +73,10 @@ int getpriority(int which, unsigned who) {
errno = rc;
rc = -1;
}
} else {
} else if (IsWindows()) {
rc = sys_getpriority_nt(which, who);
} else {
rc = enosys();
}
#else
rc = sys_getpriority(which, who);

View file

@ -71,14 +71,15 @@ _start:
// align stack to GetStackSize() so GetStackAddr() is fast
.weak ape_stack_memsz
mov $ape_stack_memsz,%r9d
mov $ape_stack_align,%r8d
cmp $_HOSTLINUX,%cl
cmove %r9d,%r8d
mov $16,%r8d
test %r9d,%r9d
cmovnz %r9,%r8
neg %r8
and %r8,%rsp
xor %ebp,%ebp
// bofram 9f
#if SupportsWindows()
// make win32 imps noop
.weak ape_idata_iat
.weak ape_idata_iatend
@ -88,6 +89,7 @@ _start:
sub %rdi,%rcx
shr $3,%ecx
rep stosq
#endif
// scan through environment varis
// find start of auxiliary values

View file

@ -9,7 +9,7 @@ COSMOPOLITAN_C_START_
*/
#if defined(__GNUC__) && defined(__x86_64__) && defined(__MNO_RED_ZONE__) && \
!defined(__STRICT_ANSI__)
!defined(__STRICT_ANSI__) && !defined(__cplusplus)
#define errno \
(*({ \
errno_t *_ep; \

View file

@ -80,7 +80,7 @@
#define FRAMESIZE 0x10000
#define PAGESIZE 0x1000 /* i386+ */
#else
#define APE_STACKSIZE 8388608 /* default 8mb stack */
#define APE_STACKSIZE 4194304 /* default 4mb stack */
#endif
#define APE_PAGESIZE 0x10000 /* i386+ */
#define APE_GUARDSIZE 0x4000 /* b/c apple m1 */

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/nt/runtime.h"
#include "libc/str/str.h"
@ -26,5 +27,6 @@
* @return 0 on success, or error code
*/
int strerror_r(int err, char *buf, size_t size) {
return strerror_wr(err, GetLastError(), buf, size);
int winerr = IsWindows() ? GetLastError() : 0;
return strerror_wr(err, winerr, buf, size);
}

View file

@ -222,7 +222,9 @@ textstartup void __enable_tls(void) {
#ifdef __x86_64__
// rewrite the executable tls opcodes in memory
__morph_tls();
if (IsWindows() || IsXnu()) {
__morph_tls();
}
#endif
// we are now allowed to use tls

View file

@ -76,7 +76,7 @@ _init_check_rdi_rsi:
jne 1b
3: .endfn _init_check_rdi_rsi
#endif
_woot: leave
leave
#elif defined(__aarch64__)
ldp x29,x30,[sp],#16
#endif

View file

@ -45,77 +45,75 @@ privileged void __morph_tls(void) {
// We check `_tls_content` which is generated by the linker script
// since it lets us determine ahead of time if _Thread_local vars
// have actually been linked into this program.
if (IsWindows() || IsXnu()) {
int n;
uint64_t w;
sigset_t mask;
unsigned m, dis;
unsigned char *p;
__morph_begin(&mask);
int n;
uint64_t w;
sigset_t mask;
unsigned m, dis;
unsigned char *p;
__morph_begin(&mask);
if (IsXnu()) {
// Apple is quite straightforward to patch. We basically
// just change the segment register, and the linear slot
// address 0x30 was promised to us, according to Go team
// https://github.com/golang/go/issues/23617
dis = 0x30;
} else {
// MSVC __declspec(thread) generates binary code for this
// %gs:0x1480 abi. So long as TlsAlloc() isn't called >64
// times we should be good.
dis = 0x1480 + __tls_index * 8;
}
// iterate over modifiable code looking for 9 byte instruction
// this would take 30 ms using xed to enable tls on python.com
for (p = _ereal; p + 9 <= __privileged_start; p += n) {
// use sse to zoom zoom to fs register prefixes
// that way it'll take 1 ms to morph python.com
while (p + 9 + 16 <= __privileged_start) {
if ((m = __builtin_ia32_pmovmskb128(
*(xmm_t *)p == (xmm_t){0144, 0144, 0144, 0144, 0144, 0144,
0144, 0144, 0144, 0144, 0144, 0144,
0144, 0144, 0144, 0144}))) {
m = __builtin_ctzll(m);
p += m;
break;
} else {
p += 16;
}
}
// we're checking for the following expression:
// 0144 == p[0] && // %fs
// 0110 == (p[1] & 0373) && // rex.w (and ignore rex.r)
// (0213 == p[2] || // mov reg/mem → reg (word-sized)
// 0003 == p[2]) && // add reg/mem → reg (word-sized)
// 0004 == (p[3] & 0307) && // mod/rm (4,reg,0) means sib → reg
// 0045 == p[4] && // sib (5,4,0) → (rbp,rsp,0) → disp32
// 0000 == p[5] && // displacement (von Neumann endian)
// 0000 == p[6] && // displacement
// 0000 == p[7] && // displacement
// 0000 == p[8] // displacement
w = READ64LE(p) & READ64LE("\377\373\377\307\377\377\377\377");
if ((w == READ64LE("\144\110\213\004\045\000\000\000") ||
w == READ64LE("\144\110\003\004\045\000\000\000")) &&
!p[8]) {
// now change the code
p[0] = 0145; // change %fs to %gs
p[5] = (dis & 0x000000ff) >> 000; // displacement
p[6] = (dis & 0x0000ff00) >> 010; // displacement
p[7] = (dis & 0x00ff0000) >> 020; // displacement
p[8] = (dis & 0xff000000) >> 030; // displacement
// advance to the next instruction
n = 9;
} else {
n = 1;
}
}
__morph_end(&mask);
if (IsXnu()) {
// Apple is quite straightforward to patch. We basically
// just change the segment register, and the linear slot
// address 0x30 was promised to us, according to Go team
// https://github.com/golang/go/issues/23617
dis = 0x30;
} else {
// MSVC __declspec(thread) generates binary code for this
// %gs:0x1480 abi. So long as TlsAlloc() isn't called >64
// times we should be good.
dis = 0x1480 + __tls_index * 8;
}
// iterate over modifiable code looking for 9 byte instruction
// this would take 30 ms using xed to enable tls on python.com
for (p = _ereal; p + 9 <= __privileged_start; p += n) {
// use sse to zoom zoom to fs register prefixes
// that way it'll take 1 ms to morph python.com
while (p + 9 + 16 <= __privileged_start) {
if ((m = __builtin_ia32_pmovmskb128(
*(xmm_t *)p == (xmm_t){0144, 0144, 0144, 0144, 0144, 0144, 0144,
0144, 0144, 0144, 0144, 0144, 0144, 0144,
0144, 0144}))) {
m = __builtin_ctzll(m);
p += m;
break;
} else {
p += 16;
}
}
// we're checking for the following expression:
// 0144 == p[0] && // %fs
// 0110 == (p[1] & 0373) && // rex.w (and ignore rex.r)
// (0213 == p[2] || // mov reg/mem → reg (word-sized)
// 0003 == p[2]) && // add reg/mem → reg (word-sized)
// 0004 == (p[3] & 0307) && // mod/rm (4,reg,0) means sib → reg
// 0045 == p[4] && // sib (5,4,0) → (rbp,rsp,0) → disp32
// 0000 == p[5] && // displacement (von Neumann endian)
// 0000 == p[6] && // displacement
// 0000 == p[7] && // displacement
// 0000 == p[8] // displacement
w = READ64LE(p) & READ64LE("\377\373\377\307\377\377\377\377");
if ((w == READ64LE("\144\110\213\004\045\000\000\000") ||
w == READ64LE("\144\110\003\004\045\000\000\000")) &&
!p[8]) {
// now change the code
p[0] = 0145; // change %fs to %gs
p[5] = (dis & 0x000000ff) >> 000; // displacement
p[6] = (dis & 0x0000ff00) >> 010; // displacement
p[7] = (dis & 0x00ff0000) >> 020; // displacement
p[8] = (dis & 0xff000000) >> 030; // displacement
// advance to the next instruction
n = 9;
} else {
n = 1;
}
}
__morph_end(&mask);
#endif
}

View file

@ -1410,6 +1410,7 @@ err:
return -1;
}
#if SupportsWindows()
textwindows int sys_close_epoll_nt(int fd) {
struct PortState *port_state;
struct TsTreeNode *tree_node;
@ -1427,6 +1428,7 @@ err:
err_check_handle(g_fds.p[fd].handle);
return -1;
}
#endif
/**
* Creates new epoll instance.

View file

@ -223,7 +223,9 @@ void testlib_runtestcases(testfn_t *start, testfn_t *end, testfn_t warmup) {
if (_weaken(testlib_enable_tmp_setup_teardown)) SetupTmpDir();
if (_weaken(SetUp)) _weaken(SetUp)();
errno = 0;
SetLastError(0);
if (IsWindows()) {
SetLastError(0);
}
if (!IsWindows()) sys_getpid();
if (warmup) warmup();
testlib_clearxmmregisters();

View file

@ -18,8 +18,10 @@
*/
#include "libc/calls/internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/dce.h"
#include "libc/mem/gc.internal.h"
#include "libc/testlib/testlib.h"
#if SupportsWindows()
char16_t p[PATH_MAX];
@ -48,3 +50,5 @@ TEST(mkntpath, testRemoveDoubleSlash) {
EXPECT_EQ(21, __mkntpath("C:\\Users\\jart\\\\.config", p));
EXPECT_STREQ(u"C:\\Users\\jart\\.config", p);
}
#endif /* SupportsWindows() */

View file

@ -100,13 +100,14 @@ TEST(pthread_setname_np, GetNameOfOtherThread) {
ASSERT_EQ(0, pthread_create(&id, 0, GetNameOfOtherThreadWorker, 0));
while (!atomic_load(&sync1)) pthread_yield();
errno_t e = pthread_getname_np(id, me, sizeof(me));
if (IsLinux() && e == ENOENT) return; // bah old kernel
if (IsLinux() && e == EACCES) return; // meh landlock
if (IsLinux() && e == ENOENT) goto GiveUp; // bah old kernel
if (IsLinux() && e == EACCES) goto GiveUp; // meh landlock
ASSERT_EQ(0, e);
EXPECT_STREQ("justine", me);
ASSERT_EQ(0, pthread_setname_np(id, "tunney"));
ASSERT_EQ(0, pthread_getname_np(id, me, sizeof(me)));
EXPECT_STREQ("tunney", me);
GiveUp:
atomic_store(&sync2, 1);
ASSERT_EQ(0, pthread_join(id, 0));
}

View file

@ -205,7 +205,7 @@ int LuaUnixSysretErrno(lua_State *L, const char *call, int olderr) {
struct UnixErrno *ep;
int i, unixerr, winerr;
unixerr = errno;
winerr = GetLastError();
winerr = IsWindows() ? GetLastError() : 0;
if (!IsTiny() && !(0 < unixerr && unixerr < (!IsWindows() ? 4096 : 65536))) {
WARNF("errno should not be %d", unixerr);
}

View file

@ -664,10 +664,7 @@ def commonpath(paths):
try:
# GetFinalPathNameByHandle is available starting with Windows 6.0.
# Windows XP and non-Windows OS'es will mock _getfinalpathname.
if sys.getwindowsversion()[:2] >= (6, 0):
_getfinalpathname = posix._getfinalpathname
else:
raise ImportError
_getfinalpathname = posix._getfinalpathname
except (AttributeError, ImportError, OSError):
# On Windows XP and earlier, two files are the same if their absolute
# pathnames are the same.

View file

@ -946,6 +946,10 @@ os__getfinalpathname(PyObject *module, PyObject *arg)
PyObject *return_value = NULL;
PyObject *path;
if (!IsWindows()) {
Py_RETURN_NONE;
}
if (!PyArg_Parse(arg, "U:_getfinalpathname", &path)) {
goto exit;
}
@ -1037,6 +1041,9 @@ os__getvolumepathname_impl(PyObject *module, PyObject *path);
static PyObject *
os__getvolumepathname(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
{
if (!IsWindows()) {
Py_RETURN_NONE;
}
PyObject *return_value = NULL;
static const char * const _keywords[] = {"path", NULL};
static _PyArg_Parser _parser = {"U:_getvolumepathname", _keywords, 0};

View file

@ -4,6 +4,7 @@
Python 3
https://docs.python.org/3/license.html │
*/
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/mem/mem.h"
#include "libc/nt/enum/formatmessageflags.h"
@ -11,6 +12,7 @@
#include "libc/nt/memory.h"
#include "libc/nt/process.h"
#include "libc/nt/runtime.h"
#include "libc/runtime/runtime.h"
#include "libc/x/x.h"
#include "third_party/python/Include/abstract.h"
#include "third_party/python/Include/dictobject.h"
@ -589,6 +591,10 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects(
PyObject *message;
PyObject *args, *v;
uint32_t err = (uint32_t)ierr;
if (!IsWindows()) {
PyErr_SetString(PyExc_SystemError, "this is not windows");
return 0;
}
if (err==0) err = GetLastError();
len = FormatMessage(
/* Error API error */

View file

@ -1032,6 +1032,11 @@ sys_getwindowsversion(PyObject *self)
void *verblock;
uint32_t verblock_size;
if (!IsWindows()) {
PyErr_SetString(PyExc_SystemError, "this is not windows");
return 0;
}
ver.dwOSVersionInfoSize = sizeof(ver);
if (!GetVersionEx(&ver))
return PyErr_SetFromWindowsErr(0);

View file

@ -1420,8 +1420,8 @@ static int zipfileGetMode(
** Both (const char*) arguments point to nul-terminated strings. Argument
** nB is the value of strlen(zB). This function returns 0 if the strings are
** identical, ignoring any trailing '/' character in either path. */
static int zipfileComparePath(const char *zA, const char *zB, int nB){
int nA = (int)strlen(zA);
static int zipfileComparePath(const char *zA, const char *zB, size_t nB){
size_t nA = strlen(zA);
if( nA>0 && zA[nA-1]=='/' ) nA--;
if( nB>0 && zB[nB-1]=='/' ) nB--;
if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;

View file

@ -82,10 +82,12 @@ extern "C" {
# define XXH_X86DISPATCH_ALLOW_AVX
#endif
#if 0 /* [jart] be quiet */
#if defined(__AVX__) && !defined(XXH_X86DISPATCH_ALLOW_AVX)
# error "Error: if xxh_x86dispatch.c is compiled with AVX enabled, the resulting binary will crash on sse2-only cpus !! " \
"If you nonetheless want to do that, please enable the XXH_X86DISPATCH_ALLOW_AVX build variable"
#endif
#endif
#ifdef __has_include
# define XXH_HAS_INCLUDE(header) __has_include(header)

View file

@ -232,7 +232,7 @@ void Assimilate(void) {
kprintf("%s: fstat() failed: %m\n", prog);
exit(14);
}
if (st.st_size < 8192) {
if (st.st_size < 4096) {
kprintf("%s: ape binaries must be at least 4096 bytes\n", prog);
exit(15);
}

View file

@ -48,6 +48,7 @@
#include "libc/mem/mem.h"
#include "libc/nexgen32e/kcpuids.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/nexgen32e/x86info.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/append.h"
#include "libc/stdio/stdio.h"
@ -911,10 +912,10 @@ int main(int argc, char *argv[]) {
}
s = basename(strdup(cmd));
if (strstr(s, "gcc")) {
if (strstr(s, "gcc") || strstr(s, "g++")) {
iscc = true;
isgcc = true;
} else if (strstr(s, "clang")) {
} else if (strstr(s, "clang") || strstr(s, "clang++")) {
iscc = true;
isclang = true;
} else if (strstr(s, "ld.bfd")) {
@ -1027,6 +1028,113 @@ int main(int argc, char *argv[]) {
if (isgcc) {
AddArg(argv[i]);
}
#ifdef __x86_64__
} else if (!strcmp(argv[i], "-march=native")) {
struct X86ProcessorModel *model;
if (X86_HAVE(ABM)) AddArg("-mabm");
if (X86_HAVE(XOP)) AddArg("-mxop");
if (X86_HAVE(SSE4A)) AddArg("-msse4a");
if (X86_HAVE(SSE3)) AddArg("-msse3");
if (X86_HAVE(SSSE3)) AddArg("-mssse3");
if (X86_HAVE(SSE4_1)) AddArg("-msse4.1");
if (X86_HAVE(SSE4_2)) AddArg("-msse4.2");
if (X86_HAVE(AVX)) AddArg("-mavx");
if (X86_HAVE(AVX2)) {
AddArg("-mavx2");
if (isgcc) {
AddArg("-msse2avx");
AddArg("-Wa,-msse2avx");
}
}
if (X86_HAVE(AVX512F)) AddArg("-mavx512f");
if (X86_HAVE(AVX512PF)) AddArg("-mavx512pf");
if (X86_HAVE(AVX512ER)) AddArg("-mavx512er");
if (X86_HAVE(AVX512CD)) AddArg("-mavx512cd");
if (X86_HAVE(AVX512VL)) AddArg("-mavx512vl");
if (X86_HAVE(AVX512BW)) AddArg("-mavx512bw");
if (X86_HAVE(AVX512DQ)) AddArg("-mavx512dq");
if (X86_HAVE(AVX512IFMA)) AddArg("-mavx512ifma");
if (X86_HAVE(AVX512VBMI)) AddArg("-mavx512vbmi");
if (X86_HAVE(SHA)) AddArg("-msha");
if (X86_HAVE(AES)) AddArg("-maes");
if (X86_HAVE(VAES)) AddArg("-mvaes");
if (X86_HAVE(PCLMUL)) AddArg("-mpclmul");
if (X86_HAVE(FSGSBASE)) AddArg("-mfsgsbase");
if (X86_HAVE(F16C)) AddArg("-mf16c");
if (X86_HAVE(FMA)) AddArg("-mfma");
if (X86_HAVE(POPCNT)) AddArg("-mpopcnt");
if (X86_HAVE(BMI)) AddArg("-mbmi");
if (X86_HAVE(BMI2)) AddArg("-mbmi2");
if (X86_HAVE(ADX)) AddArg("-madx");
if (X86_HAVE(FXSR)) AddArg("-mfxsr");
if ((model = getx86processormodel(kX86ProcessorModelKey))) {
switch (model->march) {
case X86_MARCH_CORE2:
AddArg("-march=core2");
break;
case X86_MARCH_NEHALEM:
AddArg("-march=nehalem");
break;
case X86_MARCH_WESTMERE:
AddArg("-march=westmere");
break;
case X86_MARCH_SANDYBRIDGE:
AddArg("-march=sandybridge");
break;
case X86_MARCH_IVYBRIDGE:
AddArg("-march=ivybridge");
break;
case X86_MARCH_HASWELL:
AddArg("-march=haswell");
break;
case X86_MARCH_BROADWELL:
AddArg("-march=broadwell");
break;
case X86_MARCH_SKYLAKE:
case X86_MARCH_KABYLAKE:
AddArg("-march=skylake");
break;
case X86_MARCH_CANNONLAKE:
AddArg("-march=cannonlake");
break;
case X86_MARCH_ICELAKE:
if (model->grade >= X86_GRADE_SERVER) {
AddArg("-march=icelake-server");
} else {
AddArg("-march=icelake-client");
}
break;
case X86_MARCH_TIGERLAKE:
AddArg("-march=tigerlake");
break;
case X86_MARCH_BONNELL:
case X86_MARCH_SALTWELL:
AddArg("-march=bonnell");
break;
case X86_MARCH_SILVERMONT:
case X86_MARCH_AIRMONT:
AddArg("-march=silvermont");
break;
case X86_MARCH_GOLDMONT:
AddArg("-march=goldmont");
break;
case X86_MARCH_GOLDMONTPLUS:
AddArg("-march=goldmont-plus");
break;
case X86_MARCH_TREMONT:
AddArg("-march=tremont");
break;
case X86_MARCH_KNIGHTSLANDING:
AddArg("-march=knl");
break;
case X86_MARCH_KNIGHTSMILL:
AddArg("-march=knm");
break;
}
}
#endif /* __x86_64__ */
} else if (!strcmp(argv[i], "-fsanitize=address")) {
if (isgcc && ccversion >= 6) wantasan = true;
} else if (!strcmp(argv[i], "-fsanitize=undefined")) {

View file

@ -25,7 +25,7 @@
(require 'ld-script)
(require 'make-mode)
(setq cosmo-dbg-mode "zero")
(setq cosmo-dbg-mode "dbg")
(setq cosmo-default-mode "")
(setq c-doc-comment-style 'javadown)

View file

@ -22,6 +22,8 @@
#include "libc/nt/enum/consolemodeflags.h"
#include "libc/nt/runtime.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#if defined(__x86_64__) && SupportsWindows()
int main(int argc, char *argv[]) {
if (!IsWindows()) {
@ -40,3 +42,11 @@ int main(int argc, char *argv[]) {
kNtEnableVirtualTerminalProcessing);
_Exit(0);
}
#else
int main(int argc, char *argv[]) {
fprintf(stderr,
"fixconsole not supported on this cpu arch or build config\n");
return 1;
}
#endif /* __x86_64__ && SupportsWindows() */

View file

@ -41,7 +41,7 @@
#include "libc/time/time.h"
#include "tool/decode/lib/flagger.h"
#include "tool/decode/lib/idname.h"
#ifdef __x86_64__
#if defined(__x86_64__) && SupportsWindows()
char *GetString(struct NtUnicodeString *s) {
static char buf[1024];
@ -538,4 +538,9 @@ int main(int argc, char *argv[]) {
return 0;
}
#endif /* __x86_64__ */
#else
int main(int argc, char *argv[]) {
fprintf(stderr, "printpeb not supported on this cpu arch or build config\n");
return 1;
}
#endif /* __x86_64__ && SupportsWindows() */

View file

@ -26,6 +26,7 @@
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#if defined(__x86_64__) && SupportsWindows()
/**
* @fileoverview WIN32 Virtual Memory Layout Dump Utility
@ -73,3 +74,11 @@ int main(int argc, char *argv[]) {
(DescribeNtPageFlags)(b[4], mi.Protect));
}
}
#else
int main(int argc, char *argv[]) {
fprintf(stderr,
"virtualquery not supported on this cpu arch or build config\n");
return 1;
}
#endif /* __x86_64__ && SupportsWindows() */