Make improvements to cosmocc toolchain

This commit is contained in:
Justine Tunney 2023-06-10 15:50:01 -07:00
parent 8ff48201ca
commit 2676ec55de
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
8 changed files with 205 additions and 117 deletions

View file

@ -7,15 +7,66 @@
http://creativecommons.org/publicdomain/zero/1.0/ │ http://creativecommons.org/publicdomain/zero/1.0/ │
*/ */
#endif #endif
#include "libc/mem/gc.h" #include "libc/calls/calls.h"
#include "libc/stdio/stdio.h" #include "libc/calls/struct/timespec.h"
#include "libc/x/xiso8601.h" #include "libc/str/str.h"
#include "libc/time/struct/tm.h"
/** /**
* @fileoverview ISO-8601 international high-precision timestamp printer. * @fileoverview High performance ISO-8601 timestamp formatter.
*/ */
int main(int argc, char *argv[]) { char *GetTimestamp(void) {
puts(_gc(xiso8601ts(NULL))); int x;
return 0; struct timespec ts;
_Thread_local static long last;
_Thread_local static char s[27];
_Thread_local static struct tm tm;
clock_gettime(0, &ts);
if (ts.tv_sec != last) {
localtime_r(&ts.tv_sec, &tm);
x = tm.tm_year + 1900;
s[0] = '0' + x / 1000;
s[1] = '0' + x / 100 % 10;
s[2] = '0' + x / 10 % 10;
s[3] = '0' + x % 10;
s[4] = '-';
x = tm.tm_mon + 1;
s[5] = '0' + x / 10;
s[6] = '0' + x % 10;
s[7] = '-';
x = tm.tm_mday;
s[8] = '0' + x / 10;
s[9] = '0' + x % 10;
s[10] = 'T';
x = tm.tm_hour;
s[11] = '0' + x / 10;
s[12] = '0' + x % 10;
s[13] = ':';
x = tm.tm_min;
s[14] = '0' + x / 10;
s[15] = '0' + x % 10;
s[16] = ':';
x = tm.tm_sec;
s[17] = '0' + x / 10;
s[18] = '0' + x % 10;
s[19] = '.';
s[26] = 0;
last = ts.tv_sec;
}
x = ts.tv_nsec;
s[20] = '0' + x / 100000000;
s[21] = '0' + x / 10000000 % 10;
s[22] = '0' + x / 1000000 % 10;
s[23] = '0' + x / 100000 % 10;
s[24] = '0' + x / 10000 % 10;
s[25] = '0' + x / 1000 % 10;
return s;
}
int main(int argc, char *argv[]) {
char buf[128], *p = buf;
p = stpcpy(p, GetTimestamp());
p = stpcpy(p, "\n");
write(1, buf, p - buf);
} }

View file

@ -23,11 +23,18 @@ void __assert_fail(const char *, const char *, int) _Hide relegated;
({ \ ({ \
if (__builtin_expect(!(x), 0)) { \ if (__builtin_expect(!(x), 0)) { \
__assert_fail(s, __FILE__, __LINE__); \ __assert_fail(s, __FILE__, __LINE__); \
notpossible; \ __builtin_trap(); \
} \ } \
(void)0; \ (void)0; \
}) })
#else #else
#define _npassert(x) \
({ \
if (__builtin_expect(!(x), 0)) { \
__builtin_trap(); \
} \
(void)0; \
})
#define _unassert(x) \ #define _unassert(x) \
({ \ ({ \
if (__builtin_expect(!(x), 0)) { \ if (__builtin_expect(!(x), 0)) { \
@ -35,13 +42,6 @@ void __assert_fail(const char *, const char *, int) _Hide relegated;
} \ } \
(void)0; \ (void)0; \
}) })
#define _npassert(x) \
({ \
if (__builtin_expect(!(x), 0)) { \
notpossible; \
} \
(void)0; \
})
#endif #endif
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_

View file

@ -16,7 +16,6 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/assert.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/calls/sig.internal.h" #include "libc/calls/sig.internal.h"
@ -47,7 +46,7 @@ static textwindows ssize_t sys_write_nt_impl(int fd, void *data, size_t size,
if (offset != -1) { if (offset != -1) {
// windows changes the file pointer even if overlapped is passed // windows changes the file pointer even if overlapped is passed
_npassert(SetFilePointerEx(h, 0, &p, SEEK_CUR)); SetFilePointerEx(h, 0, &p, SEEK_CUR);
} }
ok = WriteFile(h, data, _clampio(size), &sent, ok = WriteFile(h, data, _clampio(size), &sent,
@ -55,7 +54,7 @@ static textwindows ssize_t sys_write_nt_impl(int fd, void *data, size_t size,
if (offset != -1) { if (offset != -1) {
// windows clobbers file pointer even on error // windows clobbers file pointer even on error
_npassert(SetFilePointerEx(h, p, 0, SEEK_SET)); SetFilePointerEx(h, p, 0, SEEK_SET);
} }
if (ok) { if (ok) {

View file

@ -18,49 +18,15 @@
*/ */
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/atomic.h" #include "libc/atomic.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/errno.h"
#include "libc/intrin/atomic.h" #include "libc/intrin/atomic.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/intrin/weaken.h"
#include "libc/log/backtrace.internal.h"
#include "libc/log/internal.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/symbols.internal.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
relegated void __assert_fail(const char *expr, const char *file, int line) { privileged void __assert_fail(const char *expr, const char *file, int line) {
int me, owner; static atomic_bool once;
static atomic_int once;
if (!__assert_disable) { if (!__assert_disable) {
strace_enabled(-1); if (!atomic_exchange(&once, true)) {
ftrace_enabled(-1); kprintf("%s:%d: assert(%s) failed (tid %P) %m\n", file, line, expr);
owner = 0;
me = __tls_enabled ? __get_tls()->tib_tid : __pid;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
kprintf("%s:%d: assert(%s) failed (tid %d) %m\n", file, line, expr, me);
if (__vforked ||
atomic_compare_exchange_strong_explicit(
&once, &owner, me, memory_order_relaxed, memory_order_relaxed)) {
__restore_tty();
if (_weaken(ShowBacktrace)) {
_weaken(ShowBacktrace)(2, __builtin_frame_address(0));
} else if (_weaken(PrintBacktraceUsingSymbols) &&
_weaken(GetSymbolTable)) {
_weaken(PrintBacktraceUsingSymbols)(2, __builtin_frame_address(0),
_weaken(GetSymbolTable)());
} else {
kprintf("can't backtrace b/c `ShowCrashReports` not linked\n");
}
_Exitr(23);
} else if (owner == me) {
kprintf("assert failed while failing\n");
_Exitr(24);
} else {
_Exit1(25);
} }
__builtin_trap();
} }
} }

View file

@ -120,7 +120,7 @@ long _missingno();
void _weakfree(void *); void _weakfree(void *);
void *_mapanon(size_t) attributeallocsize((1)) mallocesque; void *_mapanon(size_t) attributeallocsize((1)) mallocesque;
void *_mapshared(size_t) attributeallocsize((1)) mallocesque; void *_mapshared(size_t) attributeallocsize((1)) mallocesque;
void *_mapstack(void) returnsaligned((FRAMESIZE)) mallocesque; void *_mapstack(void) returnsaligned((APE_PAGESIZE)) mallocesque;
int _freestack(void *); int _freestack(void *);
void __oom_hook(size_t); void __oom_hook(size_t);
void _peekall(void); void _peekall(void);

View file

@ -55,7 +55,7 @@ void *xrealloc(void *, size_t)
attributeallocsize((2)) dontthrow nocallback dontdiscard; attributeallocsize((2)) dontthrow nocallback dontdiscard;
void *xcalloc(size_t, size_t) attributeallocsize((1, 2)) void *xcalloc(size_t, size_t) attributeallocsize((1, 2))
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull; returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
void *xvalloc(size_t) attributeallocsize((1)) returnsaligned((FRAMESIZE)) void *xvalloc(size_t) attributeallocsize((1)) returnsaligned((APE_PAGESIZE))
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull; returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
void *xmemalign(size_t, size_t) attributeallocalign((1)) attributeallocsize((2)) void *xmemalign(size_t, size_t) attributeallocalign((1)) attributeallocsize((2))
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull; returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;

View file

@ -2,23 +2,50 @@
# #
# cosmopolitan c++ compiler # cosmopolitan c++ compiler
# #
# we assume you run the following beforehand # getting started
# #
# sudo chmod 1777 /opt # sudo chmod 1777 /opt
# cd /opt # git clone https://github.com/jart/cosmopolitan /opt/cosmo
# git clone https://github.com/jart/cosmopolitan cosmo # (cd /opt/cosmo; make -j8 toolchain)
# cd cosmo # sudo ln -sf /opt/cosmo/tool/scripts/cosmocc /usr/local/bin/cosmocc
# make -j # sudo ln -sf /opt/cosmo/tool/scripts/cosmoc++ /usr/local/bin/cosmoc++
# cosmoc++ -o hello.com hello.cc
# ./foo.com
# ./foo.com.dbg
# #
# you can then use it to build open source projects, e.g. # building open source projects
# #
# export CC=cosmocc # export CC=cosmocc
# export CXX=cosmoc++ # export CXX=cosmoc++
# export LD=cosmoc++
# ./configure --prefix=/opt/cosmos # ./configure --prefix=/opt/cosmos
# make -j # make -j
# make install # make install
# #
# cosmopolitan runtime flags
#
# ./hello.com --strace
# ./hello.com --ftrace
#
# cosmpolitan runtime libraries
#
# #include <cosmo.h>
# int main() {
# ShowCrashReports();
# __builtin_trap();
# }
#
# building programs in tiny mode
#
# export MODE=tiny
# (cd /opt/cosmo; make -j8 toolchain)
# cosmoc++ -Os -o foo.com foo.cc
#
# hardening programs with memory safety
#
# export MODE=asan
# (cd /opt/cosmo; make -j8 toolchain)
# cosmoc++ -o foo.com foo.cc
#
MODE=${MODE:-$m} MODE=${MODE:-$m}
COSMO=${COSMO:-/opt/cosmo} COSMO=${COSMO:-/opt/cosmo}
@ -36,14 +63,14 @@ fi
PLATFORM="-D__COSMOPOLITAN__" PLATFORM="-D__COSMOPOLITAN__"
PREDEF="-include libc/integral/normalize.inc" PREDEF="-include libc/integral/normalize.inc"
CCFLAGS="-g -fdata-sections -ffunction-sections -fno-pie -mno-tls-direct-seg-refs -mno-red-zone -fportcosmo" 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" CXXFLAGS="-fno-exceptions -fuse-cxa-atexit -fno-threadsafe-statics"
CPPFLAGS="-DNDEBUG -nostdinc -iquote /opt/cosmo -isystem $COSMOS/include -isystem $COSMO/libc/isystem" CPPFLAGS="-DNDEBUG -nostdinc -iquote /opt/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 -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"
LDLIBS="$COSMO/o/$MODE/third_party/libcxx/libcxx.a $COSMO/o/$MODE/cosmopolitan.a" LDLIBS="$COSMO/o/$MODE/third_party/libcxx/libcxx.a $COSMO/o/$MODE/cosmopolitan.a"
CXX="$COSMO/o/$MODE/third_party/gcc/bin/x86_64-linux-musl-g++" CXX="$COSMO/o/third_party/gcc/bin/x86_64-linux-musl-g++"
OBJCOPY="$COSMO/o/$MODE/third_party/gcc/bin/x86_64-linux-musl-objcopy" OBJCOPY="$COSMO/o/third_party/gcc/bin/x86_64-linux-musl-objcopy"
FIXUPOBJ="$COSMO/o/$MODE/tool/build/fixupobj.com" FIXUPOBJ="$COSMO/o/$MODE/tool/build/fixupobj.com"
ZIPCOPY="$COSMO/o/$MODE/tool/build/zipcopy.com" ZIPCOPY="$COSMO/o/$MODE/tool/build/zipcopy.com"
@ -57,6 +84,16 @@ if [ ! -d "$COSMOS" ]; then
exit 1 exit 1
fi fi
if [ ! -f "$CXX" ] ||
[ ! -f "$OBJCOPY" ] ||
[ ! -f "$FIXUPOBJ" ] ||
[ ! -f "$ZIPCOPY" ]; then
echo "error: cosmopolitan artifacts missing; please run" >&2
echo " cd $COSMOS" >&2
echo " make -j8 m=$MODE toolchain" >&2
exit 1
fi
# auto-install some shell libraries # auto-install some shell libraries
if [ ! -d "$COSMOS/lib" ]; then if [ ! -d "$COSMOS/lib" ]; then
mkdir "$COSMOS/lib" mkdir "$COSMOS/lib"
@ -128,24 +165,27 @@ set -- "$CXX" "$@"
printf '(cd %s; %s)\n' "$PWD" "$*" >>/tmp/build.log printf '(cd %s; %s)\n' "$PWD" "$*" >>/tmp/build.log
"$@" || exit "$@" || exit
if [ $INTENT = cc ] && [ -n "$OUTPUT" ]; then if [ -n "$OUTPUT" ]; then
"$FIXUPOBJ" "$OUTPUT" || exit if [ $INTENT = cc ] || [ $INTENT = ld ]; then
elif [ $INTENT = ld ] && [ -n "$OUTPUT" ]; then "$FIXUPOBJ" "$OUTPUT" || exit
if [ x"$OUTPUT" != x"${OUTPUT%.com}" ] || fi
[ x"$OUTPUT" != x"${OUTPUT%.exe}" ]; then if [ $INTENT = ld ]; then
# cosmocc -o foo.com ... if [ x"$OUTPUT" != x"${OUTPUT%.com}" ] ||
# -> foo.com (ape) [ x"$OUTPUT" != x"${OUTPUT%.exe}" ]; then
# -> foo.com.dbg (elf) # cosmocc -o foo.com ...
mv -f "$OUTPUT" "$OUTPUT.dbg" || exit # -> foo.com (ape)
"$OBJCOPY" -S -O binary "$OUTPUT.dbg" "$OUTPUT" || exit # -> foo.com.dbg (elf)
"$ZIPCOPY" "$OUTPUT.dbg" "$OUTPUT" || exit mv -f "$OUTPUT" "$OUTPUT.dbg" || exit
else "$OBJCOPY" -S -O binary "$OUTPUT.dbg" "$OUTPUT" || exit
# cosmocc -o foo ... "$ZIPCOPY" "$OUTPUT.dbg" "$OUTPUT" || exit
# -> foo (elf) else
# -> foo.com (ape) # cosmocc -o foo ...
# -> foo.com.dbg (elf) # -> foo (elf)
cp -f "$OUTPUT" "$OUTPUT.com.dbg" || exit # -> foo.com (ape)
"$OBJCOPY" -S -O binary "$OUTPUT" "$OUTPUT.com" || exit # -> foo.com.dbg (elf)
"$ZIPCOPY" "$OUTPUT" "$OUTPUT.com" || exit cp -f "$OUTPUT" "$OUTPUT.com.dbg" || exit
"$OBJCOPY" -S -O binary "$OUTPUT" "$OUTPUT.com" || exit
"$ZIPCOPY" "$OUTPUT" "$OUTPUT.com" || exit
fi
fi fi
fi fi

View file

@ -2,23 +2,50 @@
# #
# cosmopolitan c compiler # cosmopolitan c compiler
# #
# we assume you run the following beforehand # getting started
# #
# sudo chmod 1777 /opt # sudo chmod 1777 /opt
# cd /opt # git clone https://github.com/jart/cosmopolitan /opt/cosmo
# git clone https://github.com/jart/cosmopolitan cosmo # (cd /opt/cosmo; make -j8 toolchain)
# cd cosmo # sudo ln -sf /opt/cosmo/tool/scripts/cosmocc /usr/local/bin/cosmocc
# make -j # sudo ln -sf /opt/cosmo/tool/scripts/cosmoc++ /usr/local/bin/cosmoc++
# cosmocc -o hello.com hello.c
# ./foo.com
# ./foo.com.dbg
# #
# you can then use it to build open source projects, e.g. # building open source projects
# #
# export CC=cosmocc # export CC=cosmocc
# export CXX=cosmoc++ # export CXX=cosmoc++
# export LD=cosmoc++
# ./configure --prefix=/opt/cosmos # ./configure --prefix=/opt/cosmos
# make -j # make -j
# make install # make install
# #
# cosmopolitan runtime flags
#
# ./hello.com --strace
# ./hello.com --ftrace
#
# cosmpolitan runtime libraries
#
# #include <cosmo.h>
# int main() {
# ShowCrashReports();
# __builtin_trap();
# }
#
# building programs in tiny mode
#
# export MODE=tiny
# (cd /opt/cosmo; make -j8 toolchain)
# cosmocc -Os -o foo.com foo.c
#
# hardening programs with memory safety
#
# export MODE=asan
# (cd /opt/cosmo; make -j8 toolchain)
# cosmocc -o foo.com foo.c
#
MODE=${MODE:-$m} MODE=${MODE:-$m}
COSMO=${COSMO:-/opt/cosmo} COSMO=${COSMO:-/opt/cosmo}
@ -36,14 +63,14 @@ fi
PLATFORM="-D__COSMOPOLITAN__" PLATFORM="-D__COSMOPOLITAN__"
PREDEF="-include libc/integral/normalize.inc" PREDEF="-include libc/integral/normalize.inc"
CCFLAGS="-g -fdata-sections -ffunction-sections -fno-pie -mno-tls-direct-seg-refs -mno-red-zone -fportcosmo" CCFLAGS="-fdata-sections -ffunction-sections -fno-pie -mno-tls-direct-seg-refs -mno-red-zone -fportcosmo"
CFLAGS= CFLAGS=
CPPFLAGS="-DNDEBUG -nostdinc -iquote /opt/cosmo -isystem $COSMOS/include -isystem $COSMO/libc/isystem" CPPFLAGS="-DNDEBUG -nostdinc -iquote /opt/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 -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"
LDLIBS="$COSMO/o/$MODE/cosmopolitan.a" LDLIBS="$COSMO/o/$MODE/cosmopolitan.a"
CC="$COSMO/o/$MODE/third_party/gcc/bin/x86_64-linux-musl-gcc" CC="$COSMO/o/third_party/gcc/bin/x86_64-linux-musl-gcc"
OBJCOPY="$COSMO/o/$MODE/third_party/gcc/bin/x86_64-linux-musl-objcopy" OBJCOPY="$COSMO/o/third_party/gcc/bin/x86_64-linux-musl-objcopy"
FIXUPOBJ="$COSMO/o/$MODE/tool/build/fixupobj.com" FIXUPOBJ="$COSMO/o/$MODE/tool/build/fixupobj.com"
ZIPCOPY="$COSMO/o/$MODE/tool/build/zipcopy.com" ZIPCOPY="$COSMO/o/$MODE/tool/build/zipcopy.com"
@ -57,6 +84,16 @@ if [ ! -d "$COSMOS" ]; then
exit 1 exit 1
fi fi
if [ ! -f "$CC" ] ||
[ ! -f "$OBJCOPY" ] ||
[ ! -f "$FIXUPOBJ" ] ||
[ ! -f "$ZIPCOPY" ]; then
echo "error: cosmopolitan artifacts missing; please run" >&2
echo " cd $COSMOS" >&2
echo " make -j8 m=$MODE toolchain" >&2
exit 1
fi
# auto-install some shell libraries # auto-install some shell libraries
if [ ! -d "$COSMOS/lib" ]; then if [ ! -d "$COSMOS/lib" ]; then
mkdir "$COSMOS/lib" mkdir "$COSMOS/lib"
@ -128,24 +165,19 @@ set -- "$CC" "$@"
printf '(cd %s; %s)\n' "$PWD" "$*" >>/tmp/build.log printf '(cd %s; %s)\n' "$PWD" "$*" >>/tmp/build.log
"$@" || exit "$@" || exit
if [ $INTENT = cc ] && [ -n "$OUTPUT" ]; then if [ -n "$OUTPUT" ] && [ -f "$OUTPUT" ]; then
"$FIXUPOBJ" "$OUTPUT" || exit if [ $INTENT = cc ] || [ $INTENT = ld ]; then
elif [ $INTENT = ld ] && [ -n "$OUTPUT" ]; then "$FIXUPOBJ" "$OUTPUT" || exit
if [ x"$OUTPUT" != x"${OUTPUT%.com}" ] || fi
[ x"$OUTPUT" != x"${OUTPUT%.exe}" ]; then if [ $INTENT = ld ]; then
# cosmocc -o foo.com ... if [ x"$OUTPUT" != x"${OUTPUT%.com}" ] ||
# -> foo.com (ape) [ x"$OUTPUT" != x"${OUTPUT%.exe}" ]; then
# -> foo.com.dbg (elf) # cosmocc -o foo.com ...
mv -f "$OUTPUT" "$OUTPUT.dbg" || exit # -> foo.com (ape)
"$OBJCOPY" -S -O binary "$OUTPUT.dbg" "$OUTPUT" || exit # -> foo.com.dbg (elf)
"$ZIPCOPY" "$OUTPUT.dbg" "$OUTPUT" || exit mv -f "$OUTPUT" "$OUTPUT.dbg" || exit
else "$OBJCOPY" -S -O binary "$OUTPUT.dbg" "$OUTPUT" || exit
# cosmocc -o foo ... "$ZIPCOPY" "$OUTPUT.dbg" "$OUTPUT" || exit
# -> foo (elf) fi
# -> 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 fi