diff options
Diffstat (limited to '05')
28 files changed, 711 insertions, 64 deletions
diff --git a/05/README.md b/05/README.md index 0244a4b..a68cbbb 100644 --- a/05/README.md +++ b/05/README.md @@ -1,42 +1,42 @@ # [bootstrap](../README.md) stage 05 -This stage consists of a C compiler capable of compiling TCC (after some modifications -to TCC's source code). +This stage consists of a C compiler capable of compiling tcc (after some modifications +to tcc's source code). Run ``` $ make ``` -to build our C compiler and TCC. This will take some time (approx. 25 seconds on my computer). +to build our C compiler and tcc. This will take some time (approx. 25 seconds on my computer). This also compiles a "Hello, world!" executable, `a.out`, with our compiler. -We can now compile TCC with itself. But first, you'll need to install the header files and library files -which are needed to compile (almost) any program with TCC: +We can now compile tcc with itself. But first, you'll need to install the header files and library files +which are needed to compile (almost) any program with tcc: ``` $ sudo make install-tcc0 ``` The files will be installed to `/usr/local/lib/tcc-bootstrap`. If you want to change this, make sure to change -both the `TCCINST` variable in the makefile, and the `CONFIG_TCCDIR` macro in `config.h`. +both the `TCCINST` variable in the makefile, and the `CONFIG_TCCDIR` macro in `tcc-0.9.27/config.h`. Anyways, once this installation is done, you should be able to compile any C program with `tcc-0.9.27/tcc0`, -including TCC itself: +including tcc itself: ``` $ cd tcc-0.9.27 $ ./tcc0 tcc.c -o tcc1 ``` -Now, let's try doing the same thing, but starting with GCC instead of our C compiler: +Now, let's try doing the same thing, but starting with gcc instead of our C compiler: ``` $ gcc tcc.c -o tcc0a $ ./tcc0a tcc.c -o tcc1a ``` -In theory, these should produce the same files, since the output of TCC shouldn't depend on which compiler it was compiled with. -If they are different, then perhaps a bug *was* introduced in some early version of GCC, and replicated in all C compilers since then! +In theory, these should produce the same files, since the output of tcc shouldn't depend on which compiler it was compiled with. +If they are different, then perhaps a bug *was* introduced in some early version of gcc, and replicated in all C compilers since then! Well, only one way to find out: ``` @@ -53,9 +53,9 @@ $ diff tcc2 tcc1a $ ``` -Yes, after compiling TCC with itself one more time, we get the same executable as the GCC-TCC one. +Yes, after compiling tcc with itself one more time, we get the same executable as the gcc-tcc one. I'm not sure why `tcc1` differs from `tcc2`, but there you go. Turns out there isn't some malicious -self-replicating code hiding in GCC after all.\* +self-replicating code hiding in gcc after all.\* ## the C compiler @@ -69,7 +69,7 @@ idents.b - functions for creating mappings from identifiers to arbitrary 6 preprocess.b - preprocesses C files tokenize.b - turns preprocessing tokens into tokens (see explanation below) parse.b - turns tokens into a nice representation of the program -codegen.b - turns parse.b's representation into actual code +codegen.b - turns parse.b's representation into CPU instructions main.b - puts everything together ``` @@ -290,7 +290,7 @@ Here is a (probably incomplete) list of things we do wrong: - You can't have a variable/function/etc. called `defined`. - Various little things about when macros are evaluated in some contexts. - The horrible, horrible function `setjmp`, which surely no one uses, is not properly supported. -Oh wait, TCC uses it. Fortunately it's not critically important to TCC. +Oh wait, tcc uses it. Fortunately it's not critically important to tcc. - Wide characters and wide character strings are not supported. - The `localtime()` function assumes you are in the UTC+0 timezone. - `mktime()` always fails. @@ -317,17 +317,16 @@ rounds down, but 0.09999999999999999861222121921855432447046041488647460937501 rounds up. ``` -Good luck writing a function which handles that! +Good luck writing code which handles that! - Originally, there was a bug where negative powers of 2 were being interpreted as half of their actual value, e.g. `x = 0.25;` would set `x` to `0.125`, but `x = 4;`, `x = 0.3;`, etc. would all work just fine. -- Writing the functions in `math.h`, although probably not necessary for compiling TCC, +- Writing the functions in `math.h`, although probably not necessary for compiling tcc, was fun! There are quite a few interesting optimizations you can make, and little tricks for avoiding losses in floating-point accuracy. -- The <s>first</s> second non-trivial program I successfully compiled worked perfectly the first time I ran it! -- A very difficult to track down bug happened the first time I ran `tcc`: there was a declaration along +- A very difficult to track down bug happened the first time I ran tcc: there was a declaration along the lines of `char x[] = "a\0b\0c";` but it got compiled as `char x[] = "a";`! -- Originally, I was just treating labels the same as any other statements, but `tcc` actually has code like: +- Originally, I was just treating labels the same as any other statements, but tcc actually has code like: ``` ... goto lbl; @@ -337,7 +336,7 @@ if (some_condition) ``` so the `do_something();` was not being considered as part of the `if` statement. - The first time I compiled tcc with itself (and then with itself again), I actually got a different -executable from the GCC one. After spending a long time looking at disassemblies, I found the culprit: +executable from the gcc one. After spending a long time looking at disassemblies, I found the culprit: ``` # if defined(__linux__) tcc_define_symbol(s, "__linux__", NULL); @@ -345,8 +344,9 @@ executable from the GCC one. After spending a long time looking at disassemblies # endif ``` If the `__linux__` macro is defined (to indicate that the target OS is linux), -TCC will also define the `__linux__` macro. Unlike GCC, our compiler doesn't define the `__linux__` macro, -so when it's used to compile TCC, TCC won't define it either, no matter how many times you compile it +tcc will also define the `__linux__` macro in any programs it compiles. +Unlike gcc, our compiler doesn't define the `__linux__` macro, +so when it's used to compile tcc, tcc won't define it either, no matter how many times you compile it with itself! ## modifications of tcc's source code @@ -359,7 +359,7 @@ here. - First, we (and C89) don't allow a comma after the last member in an initializer. In several places, the last comma in an initializer/enum definition was removed, or an irrelevant entry was added to the end. - Global variables were sometimes declared twice, which we don't support. -So, a bunch of duplicate declarations were removed. +So a bunch of duplicate declarations were removed. - The `# if defined(__linux__)` and `# endif` mentioned above were removed. - In a bunch of places, `ELFW(something)` had to be replaced with `ELF64_something` due to subtleties of how we evaluate macros. @@ -368,12 +368,12 @@ some initializers were replaced by functions called at the top of `main`. - In several places, `default:` had to be moved to after every `case` label. - In two places, `-some_long_double_expression` had to be replaced with a function call to `negate_ld` (a function I wrote for negating long doubles). -This is because TCC only supports negating long doubles if -the compiler used to compile it has an 80-bit long double type, which our compiler doesn't. -- `\0` was replaced with `\n` as a separator for keyword names. -- Forced TCC to use `R_X86_64_PC32` relocations, because its `plt` code doesn't seem to work for static +This is because tcc only supports negating long doubles if +the compiler which compiled it has an 80-bit long double type, and our compiler doesn't. +- `\0` was replaced with `\n` as a separator for keyword names in the `tcc_keywords` global variable. +- Forced tcc to use `R_X86_64_PC32` relocations, because its `plt` code doesn't seem to work for static executables. -- Lastly, there's the `config.h` file, which is normally produced by TCC's `configure` script, +- Lastly, there's the `config.h` file, which is normally produced by tcc's `configure` script, but it's easy to write one manually: ``` #define TCC_VERSION "0.9.27" @@ -386,30 +386,62 @@ but it's easy to write one manually: ``` The last line causes the `inline` keyword (added in C99) to be ignored. -Fewer changes would've been needed for an older version of TCC, but older versions didn't support -x86-64 assembly, which might end up being relevant... - ## \*libc -If you look in TCC's source code, you will not find implementations of any of the C standard library functions. -So how can programs compiled with TCC use those functions? +If you look in tcc's source code, you will not find implementations of any of the C standard library functions. +So how can programs compiled with tcc use those functions? -When a program compiled with TCC (under default settings) calls `printf`, say, it actually gets the instructions +When a program compiled with tcc (under default settings) calls `printf`, say, it actually gets the instructions for `printf` from a separate library file (called something like `/usr/lib/x86_64-linux-gnu/libc-2.31.so`). There are very good reasons for this: for example, if there a security bug were found in `printf`, it would be much easier to replace the library file than re-compile every program which uses `printf`. Now this library file is itself compiled from C source files (typically glibc). -So, we can't really say that the self-compiled TCC was built from scratch, and there could be malicious +So, we can't really say that the self-compiled tcc was built from scratch, and there could be malicious self-replicating code in glibc. -You can't compile glibc with TCC, but -it's possible to build an old version of `musl`, an alternate libc +### compiling glibc + +You can't compile glibc with tcc, but +it's possible to build an old version of musl, an alternate libc (you can run `CC=../tcc-0.9.27/tcc0 make` in the `musl-0.6.0` directory here). -You should be able to use musl alongside TCC to build an old version of GCC (git revision -`79a6d9b7ff3822675ee44d8d6cad86027dadd664` seems workable). This also requires -building several tools needed to compile GCC. You should then be able to build (possibly an old version of) -glibc, and with that, a modern version of GCC. -This is all extremely tedious, though, so I'm not planning on doing it anytime soon. +You should be able to use musl alongside tcc to build an old version of gcc. This also requires +building several tools needed to compile gcc. You should then be able to build an old version of +glibc, and with that, a modern version of gcc. + +Well, I tried this. And it is an absolute nightmare. +GNU has created a horrible web of programs that all depend on each other. +According to the recommended build process, you need awk to build awk, sed to build sed, +sed to build grep, etc. Here was a "guide" I was starting to write for how to +get to glibc: + +- install tcc, musl +- build mrsh, make, basic utilities +- chroot +- build & install coreutils +- build & install dash +- build & install sed-4.2 +- build & install ld, as (from binutils) +- build gcc +- build & install grep-3.7 +- build & install awk +- build & install bash +- build & install glibc (didn't work) + +Each of these programs uses a `./configure` script to set up the code and Makefiles. +These scripts are basically impossible to use without already having +most of these programs. So, I resorted to configuring the build with +the ordinary binary versions of `sed`, etc. I had on my machine. +This made broken Makefiles which I spent hours editing by hand +-- and is it really compiled from scratch if it's built from +computer-generated source files and Makefiles? +And although the developers at GNU +refrain from declaring variables after statements, and keep old-style function declarations +to support compilers from the 80s; they *still* manage to use gcc-specific extensions, and +not even extensions that all versions of gcc support! +After hours and hours of fixing compiler errors, I decided to give up. + +THIS WAY LIES MADNESS. + diff --git a/05/musl-0.6.0/.gitignore b/05/musl-0.6.0/.gitignore index e0292b1..16b8a37 100644 --- a/05/musl-0.6.0/.gitignore +++ b/05/musl-0.6.0/.gitignore @@ -1,2 +1,3 @@ *.o *.a +musl-gcc diff --git a/05/musl-0.6.0/Makefile b/05/musl-0.6.0/Makefile index 28233b8..9d40be5 100644 --- a/05/musl-0.6.0/Makefile +++ b/05/musl-0.6.0/Makefile @@ -8,6 +8,7 @@ # Do not make changes here. # +CC = ../tcc-0.9.27/tcc0 exec_prefix = /usr/local/musl-bootstrap bindir = $(exec_prefix)/bin @@ -16,7 +17,7 @@ includedir = $(prefix)/include libdir = $(prefix)/lib SRCS = $(sort $(wildcard src/*/*.c)) -OBJS = $(SRCS:.c=.o) src/alloca86_64-bt.o src/alloca86_64.o src/libtcc1.o src/va_list.o src/syscall56.o +OBJS = $(SRCS:.c=.o) src/alloca86_64-bt.o src/alloca86_64.o src/libtcc1.o src/va_list.o src/syscall.o LOBJS = $(OBJS:.o=.lo) GENH = include/bits/alltypes.h @@ -44,9 +45,10 @@ all: $(ALL_LIBS) $(ALL_TOOLS) install: $(ALL_LIBS:lib/%=$(DESTDIR)$(libdir)/%) $(ALL_INCLUDES:include/%=$(DESTDIR)$(includedir)/%) $(ALL_TOOLS:tools/%=$(DESTDIR)$(bindir)/%) -src/syscall56.o: src/syscall56.s +src/syscall.o: src/syscall.s $(CC) -c -o $@ $< - +src/%.o: ../tcc-0.9.27/lib/%.o + cp $< $@ clean: rm -f crt/*.o rm -f $(OBJS) diff --git a/05/musl-0.6.0/arch/x86_64/bits/stat.h b/05/musl-0.6.0/arch/x86_64/bits/stat.h index 2145796..64dab33 100644 --- a/05/musl-0.6.0/arch/x86_64/bits/stat.h +++ b/05/musl-0.6.0/arch/x86_64/bits/stat.h @@ -20,3 +20,23 @@ struct stat { struct timespec st_ctim; long __unused[3]; }; + +struct stat64 { + unsigned long st_dev; + ino_t st_ino; + nlink_t st_nlink; + + mode_t st_mode; + uid_t st_uid; + gid_t st_gid; + unsigned int __pad0; + dev_t st_rdev; + off_t st_size; + blksize_t st_blksize; + blkcnt_t st_blocks; + + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + long __unused[3]; +}; diff --git a/05/musl-0.6.0/arch/x86_64/bits/stdarg.h b/05/musl-0.6.0/arch/x86_64/bits/stdarg.h index 99fee04..10ce733 100644 --- a/05/musl-0.6.0/arch/x86_64/bits/stdarg.h +++ b/05/musl-0.6.0/arch/x86_64/bits/stdarg.h @@ -1,2 +1,79 @@ -#include "/usr/local/tcc-bootstrap/include/stdarg.h" +#ifndef _STDARG_H +#define _STDARG_H +#ifdef __x86_64__ +#ifndef _WIN64 + +//This should be in sync with the declaration on our lib/libtcc1.c +/* GCC compatible definition of va_list. */ +typedef struct { + unsigned int gp_offset; + unsigned int fp_offset; + union { + unsigned int overflow_offset; + char *overflow_arg_area; + }; + char *reg_save_area; +} __va_list_struct; + +typedef __va_list_struct va_list[1]; + +void __va_start(__va_list_struct *ap, void *fp); +void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align); + +#define va_start(ap, last) __va_start(ap, __builtin_frame_address(0)) +#define va_arg(ap, type) \ + (*(type *)(__va_arg(ap, __builtin_va_arg_types(type), sizeof(type), __alignof__(type)))) +#define va_copy(dest, src) (*(dest) = *(src)) +#define va_end(ap) + +/* avoid conflicting definition for va_list on Macs. */ +#define _VA_LIST_T + +#else /* _WIN64 */ +typedef char *va_list; +#define va_start(ap,last) __builtin_va_start(ap,last) +#define va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \ + ? **(t **)((ap += 8) - 8) : *(t *)((ap += 8) - 8)) +#define va_copy(dest, src) ((dest) = (src)) +#define va_end(ap) +#endif + +#elif __arm__ +typedef char *va_list; +#define _tcc_alignof(type) ((int)&((struct {char c;type x;} *)0)->x) +#define _tcc_align(addr,type) (((unsigned)addr + _tcc_alignof(type) - 1) \ + & ~(_tcc_alignof(type) - 1)) +#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3) +#define va_arg(ap,type) (ap = (void *) ((_tcc_align(ap,type)+sizeof(type)+3) \ + &~3), *(type *)(ap - ((sizeof(type)+3)&~3))) +#define va_copy(dest, src) (dest) = (src) +#define va_end(ap) + +#elif defined(__aarch64__) +typedef struct { + void *__stack; + void *__gr_top; + void *__vr_top; + int __gr_offs; + int __vr_offs; +} va_list; +#define va_start(ap, last) __va_start(ap, last) +#define va_arg(ap, type) __va_arg(ap, type) +#define va_end(ap) +#define va_copy(dest, src) ((dest) = (src)) + +#else /* __i386__ */ +typedef char *va_list; +/* only correct for i386 */ +#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3) +#define va_arg(ap,type) (ap += (sizeof(type)+3)&~3, *(type *)(ap - ((sizeof(type)+3)&~3))) +#define va_copy(dest, src) (dest) = (src) +#define va_end(ap) +#endif + +/* fix a buggy dependency on GCC in libio.h */ +typedef va_list __gnuc_va_list; +#define _VA_LIST_DEFINED + +#endif /* _STDARG_H */ diff --git a/05/musl-0.6.0/arch/x86_64/syscall.h b/05/musl-0.6.0/arch/x86_64/syscall.h index 544e9cc..acebd76 100644 --- a/05/musl-0.6.0/arch/x86_64/syscall.h +++ b/05/musl-0.6.0/arch/x86_64/syscall.h @@ -24,6 +24,7 @@ extern long __syscall_ret(unsigned long); #define SYSCALL "syscall" +#if 0 static inline long syscall0(long n) { unsigned long ret; @@ -63,7 +64,6 @@ static inline long syscall4(long n, long a1, long a2, long a3, long a4) return __syscall_ret(ret); } -#if 0 static inline long syscall5(long n, long a1, long a2, long a3, long a4, long a5) { @@ -88,6 +88,11 @@ static inline long syscall6(long n, long a1, long a2, long a3, long a4, return __syscall_ret(ret); } #else +extern long syscall0(long); +extern long syscall1(long, long); +extern long syscall2(long, long, long); +extern long syscall3(long, long, long, long); +extern long syscall4(long, long, long, long, long); extern long syscall5(long, long, long, long, long, long); extern long syscall6(long, long, long, long, long, long, long); #endif diff --git a/05/musl-0.6.0/include/dirent.h b/05/musl-0.6.0/include/dirent.h index a917093..2e8c996 100644 --- a/05/musl-0.6.0/include/dirent.h +++ b/05/musl-0.6.0/include/dirent.h @@ -34,6 +34,33 @@ int dirfd(DIR *); int alphasort(const struct dirent **, const struct dirent **); int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **)); +/* File types for `d_type'. */ +enum + { + DT_UNKNOWN = 0, +# define DT_UNKNOWN DT_UNKNOWN + DT_FIFO = 1, +# define DT_FIFO DT_FIFO + DT_CHR = 2, +# define DT_CHR DT_CHR + DT_DIR = 4, +# define DT_DIR DT_DIR + DT_BLK = 6, +# define DT_BLK DT_BLK + DT_REG = 8, +# define DT_REG DT_REG + DT_LNK = 10, +# define DT_LNK DT_LNK + DT_SOCK = 12, +# define DT_SOCK DT_SOCK + DT_WHT = 14 +# define DT_WHT DT_WHT + }; + +/* Convert between stat structure types and directory types. */ +# define IFTODT(mode) (((mode) & 0170000) >> 12) +# define DTTOIF(dirtype) ((dirtype) << 12) + #ifdef __cplusplus extern } #endif diff --git a/05/musl-0.6.0/include/stdarg.h b/05/musl-0.6.0/include/stdarg.h index 0d915ab..1a455d2 100644 --- a/05/musl-0.6.0/include/stdarg.h +++ b/05/musl-0.6.0/include/stdarg.h @@ -1 +1,87 @@ -#include "/usr/local/tcc-bootstrap/include/stdarg.h" +#ifndef _STDARG_H +#define _STDARG_H + +#ifdef __GNUC__ +#define va_list __builtin_va_list +#define va_arg __builtin_va_arg +#define va_start __builtin_va_start +#define va_end __builtin_va_end +#define va_copy __builtin_va_copy +#else +#ifdef __x86_64__ +#ifndef _WIN64 + +//This should be in sync with the declaration on our lib/libtcc1.c +/* GCC compatible definition of va_list. */ +typedef struct { + unsigned int gp_offset; + unsigned int fp_offset; + union { + unsigned int overflow_offset; + char *overflow_arg_area; + }; + char *reg_save_area; +} __va_list_struct; + +typedef __va_list_struct va_list[1]; + +void __va_start(__va_list_struct *ap, void *fp); +void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align); + +#define va_start(ap, last) __va_start(ap, __builtin_frame_address(0)) +#define va_arg(ap, type) \ + (*(type *)(__va_arg(ap, __builtin_va_arg_types(type), sizeof(type), __alignof__(type)))) +#define va_copy(dest, src) (*(dest) = *(src)) +#define va_end(ap) + +/* avoid conflicting definition for va_list on Macs. */ +#define _VA_LIST_T + +#else /* _WIN64 */ +typedef char *va_list; +#define va_start(ap,last) __builtin_va_start(ap,last) +#define va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \ + ? **(t **)((ap += 8) - 8) : *(t *)((ap += 8) - 8)) +#define va_copy(dest, src) ((dest) = (src)) +#define va_end(ap) +#endif + +#elif __arm__ +typedef char *va_list; +#define _tcc_alignof(type) ((int)&((struct {char c;type x;} *)0)->x) +#define _tcc_align(addr,type) (((unsigned)addr + _tcc_alignof(type) - 1) \ + & ~(_tcc_alignof(type) - 1)) +#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3) +#define va_arg(ap,type) (ap = (void *) ((_tcc_align(ap,type)+sizeof(type)+3) \ + &~3), *(type *)(ap - ((sizeof(type)+3)&~3))) +#define va_copy(dest, src) (dest) = (src) +#define va_end(ap) + +#elif defined(__aarch64__) +typedef struct { + void *__stack; + void *__gr_top; + void *__vr_top; + int __gr_offs; + int __vr_offs; +} va_list; +#define va_start(ap, last) __va_start(ap, last) +#define va_arg(ap, type) __va_arg(ap, type) +#define va_end(ap) +#define va_copy(dest, src) ((dest) = (src)) + +#else /* __i386__ */ +typedef char *va_list; +/* only correct for i386 */ +#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3) +#define va_arg(ap,type) (ap += (sizeof(type)+3)&~3, *(type *)(ap - ((sizeof(type)+3)&~3))) +#define va_copy(dest, src) (dest) = (src) +#define va_end(ap) +#endif + +/* fix a buggy dependency on GCC in libio.h */ +typedef va_list __gnuc_va_list; +#define _VA_LIST_DEFINED +#endif + +#endif /* _STDARG_H */ diff --git a/05/musl-0.6.0/include/sys/mtio.h b/05/musl-0.6.0/include/sys/mtio.h new file mode 100644 index 0000000..b77b7e7 --- /dev/null +++ b/05/musl-0.6.0/include/sys/mtio.h @@ -0,0 +1,276 @@ +/* Structures and definitions for magnetic tape I/O control commands. + Copyright (C) 1996-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +/* Written by H. Bergman <hennus@cybercomm.nl>. */ + +#ifndef _SYS_MTIO_H +#define _SYS_MTIO_H 1 + +/* Get necessary definitions from system and kernel headers. */ +#include <sys/types.h> +#include <sys/ioctl.h> + + +/* Structure for MTIOCTOP - magnetic tape operation command. */ +struct mtop + { + short int mt_op; /* Operations defined below. */ + int mt_count; /* How many of them. */ + }; +#define _IOT_mtop /* Hurd ioctl type field. */ \ + _IOT (_IOTS (short), 1, _IOTS (int), 1, 0, 0) + +/* Magnetic Tape operations [Not all operations supported by all drivers]. */ +#define MTRESET 0 /* +reset drive in case of problems. */ +#define MTFSF 1 /* Forward space over FileMark, + * position at first record of next file. */ +#define MTBSF 2 /* Backward space FileMark (position before FM). */ +#define MTFSR 3 /* Forward space record. */ +#define MTBSR 4 /* Backward space record. */ +#define MTWEOF 5 /* Write an end-of-file record (mark). */ +#define MTREW 6 /* Rewind. */ +#define MTOFFL 7 /* Rewind and put the drive offline (eject?). */ +#define MTNOP 8 /* No op, set status only (read with MTIOCGET). */ +#define MTRETEN 9 /* Retension tape. */ +#define MTBSFM 10 /* +backward space FileMark, position at FM. */ +#define MTFSFM 11 /* +forward space FileMark, position at FM. */ +#define MTEOM 12 /* Goto end of recorded media (for appending files). + MTEOM positions after the last FM, ready for + appending another file. */ +#define MTERASE 13 /* Erase tape -- be careful! */ + +#define MTRAS1 14 /* Run self test 1 (nondestructive). */ +#define MTRAS2 15 /* Run self test 2 (destructive). */ +#define MTRAS3 16 /* Reserved for self test 3. */ + +#define MTSETBLK 20 /* Set block length (SCSI). */ +#define MTSETDENSITY 21 /* Set tape density (SCSI). */ +#define MTSEEK 22 /* Seek to block (Tandberg, etc.). */ +#define MTTELL 23 /* Tell block (Tandberg, etc.). */ +#define MTSETDRVBUFFER 24 /* Set the drive buffering according to SCSI-2. + Ordinary buffered operation with code 1. */ +#define MTFSS 25 /* Space forward over setmarks. */ +#define MTBSS 26 /* Space backward over setmarks. */ +#define MTWSM 27 /* Write setmarks. */ + +#define MTLOCK 28 /* Lock the drive door. */ +#define MTUNLOCK 29 /* Unlock the drive door. */ +#define MTLOAD 30 /* Execute the SCSI load command. */ +#define MTUNLOAD 31 /* Execute the SCSI unload command. */ +#define MTCOMPRESSION 32/* Control compression with SCSI mode page 15. */ +#define MTSETPART 33 /* Change the active tape partition. */ +#define MTMKPART 34 /* Format the tape with one or two partitions. */ + +/* structure for MTIOCGET - mag tape get status command */ + +struct mtget + { + long int mt_type; /* Type of magtape device. */ + long int mt_resid; /* Residual count: (not sure) + number of bytes ignored, or + number of files not skipped, or + number of records not skipped. */ + /* The following registers are device dependent. */ + long int mt_dsreg; /* Status register. */ + long int mt_gstat; /* Generic (device independent) status. */ + long int mt_erreg; /* Error register. */ + /* The next two fields are not always used. */ + int mt_fileno; /* Number of current file on tape. */ + int mt_blkno; /* Current block number. */ + }; +#define _IOT_mtget /* Hurd ioctl type field. */ \ + _IOT (_IOTS (long), 7, 0, 0, 0, 0) + + +/* Constants for mt_type. Not all of these are supported, and + these are not all of the ones that are supported. */ +#define MT_ISUNKNOWN 0x01 +#define MT_ISQIC02 0x02 /* Generic QIC-02 tape streamer. */ +#define MT_ISWT5150 0x03 /* Wangtek 5150EQ, QIC-150, QIC-02. */ +#define MT_ISARCHIVE_5945L2 0x04 /* Archive 5945L-2, QIC-24, QIC-02?. */ +#define MT_ISCMSJ500 0x05 /* CMS Jumbo 500 (QIC-02?). */ +#define MT_ISTDC3610 0x06 /* Tandberg 6310, QIC-24. */ +#define MT_ISARCHIVE_VP60I 0x07 /* Archive VP60i, QIC-02. */ +#define MT_ISARCHIVE_2150L 0x08 /* Archive Viper 2150L. */ +#define MT_ISARCHIVE_2060L 0x09 /* Archive Viper 2060L. */ +#define MT_ISARCHIVESC499 0x0A /* Archive SC-499 QIC-36 controller. */ +#define MT_ISQIC02_ALL_FEATURES 0x0F /* Generic QIC-02 with all features. */ +#define MT_ISWT5099EEN24 0x11 /* Wangtek 5099-een24, 60MB, QIC-24. */ +#define MT_ISTEAC_MT2ST 0x12 /* Teac MT-2ST 155mb drive, + Teac DC-1 card (Wangtek type). */ +#define MT_ISEVEREX_FT40A 0x32 /* Everex FT40A (QIC-40). */ +#define MT_ISDDS1 0x51 /* DDS device without partitions. */ +#define MT_ISDDS2 0x52 /* DDS device with partitions. */ +#define MT_ISSCSI1 0x71 /* Generic ANSI SCSI-1 tape unit. */ +#define MT_ISSCSI2 0x72 /* Generic ANSI SCSI-2 tape unit. */ + +/* QIC-40/80/3010/3020 ftape supported drives. + 20bit vendor ID + 0x800000 (see vendors.h in ftape distribution). */ +#define MT_ISFTAPE_UNKNOWN 0x800000 /* obsolete */ +#define MT_ISFTAPE_FLAG 0x800000 + +struct mt_tape_info + { + long int t_type; /* Device type id (mt_type). */ + char *t_name; /* Descriptive name. */ + }; + +#define MT_TAPE_INFO \ + { \ + {MT_ISUNKNOWN, "Unknown type of tape device"}, \ + {MT_ISQIC02, "Generic QIC-02 tape streamer"}, \ + {MT_ISWT5150, "Wangtek 5150, QIC-150"}, \ + {MT_ISARCHIVE_5945L2, "Archive 5945L-2"}, \ + {MT_ISCMSJ500, "CMS Jumbo 500"}, \ + {MT_ISTDC3610, "Tandberg TDC 3610, QIC-24"}, \ + {MT_ISARCHIVE_VP60I, "Archive VP60i, QIC-02"}, \ + {MT_ISARCHIVE_2150L, "Archive Viper 2150L"}, \ + {MT_ISARCHIVE_2060L, "Archive Viper 2060L"}, \ + {MT_ISARCHIVESC499, "Archive SC-499 QIC-36 controller"}, \ + {MT_ISQIC02_ALL_FEATURES, "Generic QIC-02 tape, all features"}, \ + {MT_ISWT5099EEN24, "Wangtek 5099-een24, 60MB"}, \ + {MT_ISTEAC_MT2ST, "Teac MT-2ST 155mb data cassette drive"}, \ + {MT_ISEVEREX_FT40A, "Everex FT40A, QIC-40"}, \ + {MT_ISSCSI1, "Generic SCSI-1 tape"}, \ + {MT_ISSCSI2, "Generic SCSI-2 tape"}, \ + {0, NULL} \ + } + + +/* Structure for MTIOCPOS - mag tape get position command. */ + +struct mtpos + { + long int mt_blkno; /* Current block number. */ + }; +#define _IOT_mtpos /* Hurd ioctl type field. */ \ + _IOT_SIMPLE (long) + + +/* Structure for MTIOCGETCONFIG/MTIOCSETCONFIG primarily intended + as an interim solution for QIC-02 until DDI is fully implemented. */ +struct mtconfiginfo + { + long int mt_type; /* Drive type. */ + long int ifc_type; /* Interface card type. */ + unsigned short int irqnr; /* IRQ number to use. */ + unsigned short int dmanr; /* DMA channel to use. */ + unsigned short int port; /* IO port base address. */ + + unsigned long int debug; /* Debugging flags. */ + + unsigned have_dens:1; + unsigned have_bsf:1; + unsigned have_fsr:1; + unsigned have_bsr:1; + unsigned have_eod:1; + unsigned have_seek:1; + unsigned have_tell:1; + unsigned have_ras1:1; + unsigned have_ras2:1; + unsigned have_ras3:1; + unsigned have_qfa:1; + + unsigned pad1:5; + char reserved[10]; + }; +#define _IOT_mtconfiginfo /* Hurd ioctl type field. */ \ + _IOT (_IOTS (long), 2, _IOTS (short), 3, _IOTS (long), 1) /* XXX wrong */ + + +/* Magnetic tape I/O control commands. */ +#define MTIOCTOP _IOW('m', 1, struct mtop) /* Do a mag tape op. */ +#define MTIOCGET _IOR('m', 2, struct mtget) /* Get tape status. */ +#define MTIOCPOS _IOR('m', 3, struct mtpos) /* Get tape position.*/ + +/* The next two are used by the QIC-02 driver for runtime reconfiguration. + See tpqic02.h for struct mtconfiginfo. */ +#define MTIOCGETCONFIG _IOR('m', 4, struct mtconfiginfo) /* Get tape config.*/ +#define MTIOCSETCONFIG _IOW('m', 5, struct mtconfiginfo) /* Set tape config.*/ + +/* Generic Mag Tape (device independent) status macros for examining + mt_gstat -- HP-UX compatible. + There is room for more generic status bits here, but I don't + know which of them are reserved. At least three or so should + be added to make this really useful. */ +#define GMT_EOF(x) ((x) & 0x80000000) +#define GMT_BOT(x) ((x) & 0x40000000) +#define GMT_EOT(x) ((x) & 0x20000000) +#define GMT_SM(x) ((x) & 0x10000000) /* DDS setmark */ +#define GMT_EOD(x) ((x) & 0x08000000) /* DDS EOD */ +#define GMT_WR_PROT(x) ((x) & 0x04000000) +/* #define GMT_ ? ((x) & 0x02000000) */ +#define GMT_ONLINE(x) ((x) & 0x01000000) +#define GMT_D_6250(x) ((x) & 0x00800000) +#define GMT_D_1600(x) ((x) & 0x00400000) +#define GMT_D_800(x) ((x) & 0x00200000) +/* #define GMT_ ? ((x) & 0x00100000) */ +/* #define GMT_ ? ((x) & 0x00080000) */ +#define GMT_DR_OPEN(x) ((x) & 0x00040000) /* Door open (no tape). */ +/* #define GMT_ ? ((x) & 0x00020000) */ +#define GMT_IM_REP_EN(x) ((x) & 0x00010000) /* Immediate report mode.*/ +/* 16 generic status bits unused. */ + + +/* SCSI-tape specific definitions. Bitfield shifts in the status */ +#define MT_ST_BLKSIZE_SHIFT 0 +#define MT_ST_BLKSIZE_MASK 0xffffff +#define MT_ST_DENSITY_SHIFT 24 +#define MT_ST_DENSITY_MASK 0xff000000 + +#define MT_ST_SOFTERR_SHIFT 0 +#define MT_ST_SOFTERR_MASK 0xffff + +/* Bitfields for the MTSETDRVBUFFER ioctl. */ +#define MT_ST_OPTIONS 0xf0000000 +#define MT_ST_BOOLEANS 0x10000000 +#define MT_ST_SETBOOLEANS 0x30000000 +#define MT_ST_CLEARBOOLEANS 0x40000000 +#define MT_ST_WRITE_THRESHOLD 0x20000000 +#define MT_ST_DEF_BLKSIZE 0x50000000 +#define MT_ST_DEF_OPTIONS 0x60000000 + +#define MT_ST_BUFFER_WRITES 0x1 +#define MT_ST_ASYNC_WRITES 0x2 +#define MT_ST_READ_AHEAD 0x4 +#define MT_ST_DEBUGGING 0x8 +#define MT_ST_TWO_FM 0x10 +#define MT_ST_FAST_MTEOM 0x20 +#define MT_ST_AUTO_LOCK 0x40 +#define MT_ST_DEF_WRITES 0x80 +#define MT_ST_CAN_BSR 0x100 +#define MT_ST_NO_BLKLIMS 0x200 +#define MT_ST_CAN_PARTITIONS 0x400 +#define MT_ST_SCSI2LOGICAL 0x800 + +/* The mode parameters to be controlled. Parameter chosen with bits 20-28. */ +#define MT_ST_CLEAR_DEFAULT 0xfffff +#define MT_ST_DEF_DENSITY (MT_ST_DEF_OPTIONS | 0x100000) +#define MT_ST_DEF_COMPRESSION (MT_ST_DEF_OPTIONS | 0x200000) +#define MT_ST_DEF_DRVBUFFER (MT_ST_DEF_OPTIONS | 0x300000) + +/* The offset for the arguments for the special HP changer load command. */ +#define MT_ST_HPLOADER_OFFSET 10000 + + +/* Specify default tape device. */ +#ifndef DEFTAPE +# define DEFTAPE "/dev/tape" +#endif + +#endif /* mtio.h */ diff --git a/05/musl-0.6.0/src/malloc/malloc.c b/05/musl-0.6.0/src/malloc/malloc.c index d9a30fe..29f9760 100644 --- a/05/musl-0.6.0/src/malloc/malloc.c +++ b/05/musl-0.6.0/src/malloc/malloc.c @@ -324,7 +324,7 @@ void *malloc(size_t n) { struct chunk *c; int i, j; - +if (n == 0) n = 1;/* everyone depends on this behavior for some fucking reason */ if (!n || adjust_size(&n) < 0) return 0; if (n > MMAP_THRESHOLD) { diff --git a/05/musl-0.6.0/src/mman/madvise.c b/05/musl-0.6.0/src/mman/madvise.c index f03647c..c4ef799 100644 --- a/05/musl-0.6.0/src/mman/madvise.c +++ b/05/musl-0.6.0/src/mman/madvise.c @@ -7,4 +7,7 @@ int __madvise(void *addr, size_t len, int advice) return syscall3(__NR_madvise, (long)addr, len, advice); } -weak_alias(__madvise, madvise); +int madvise(void *addr, size_t len, int advice) +{ + return syscall3(__NR_madvise, (long)addr, len, advice); +} diff --git a/05/musl-0.6.0/src/mman/mmap.c b/05/musl-0.6.0/src/mman/mmap.c index 5be6e12..665e2ec 100644 --- a/05/musl-0.6.0/src/mman/mmap.c +++ b/05/musl-0.6.0/src/mman/mmap.c @@ -17,6 +17,16 @@ void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off) #endif } -weak_alias(__mmap, mmap); +void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t off) +{ + if (sizeof(off_t) > sizeof(long)) + if (((long)off & 0xfff) | ((long)((unsigned long long)off>>(12 + 8*(sizeof(off_t)-sizeof(long)))))) + start = (void *)-1; +#ifdef __NR_mmap2 + return (void *)syscall6(__NR_mmap2, (long)start, len, prot, flags, fd, off>>12); +#else + return (void *)syscall6(__NR_mmap, (long)start, len, prot, flags, fd, off); +#endif +} LFS64(mmap); diff --git a/05/musl-0.6.0/src/mman/munmap.c b/05/musl-0.6.0/src/mman/munmap.c index c9661cd..d1777e3 100644 --- a/05/musl-0.6.0/src/mman/munmap.c +++ b/05/musl-0.6.0/src/mman/munmap.c @@ -8,4 +8,7 @@ int __munmap(void *start, size_t len) return syscall2(__NR_munmap, (long)start, len); } -weak_alias(__munmap, munmap); +int munmap(void *start, size_t len) +{ + return syscall2(__NR_munmap, (long)start, len); +} diff --git a/05/musl-0.6.0/src/signal/sigaction.c b/05/musl-0.6.0/src/signal/sigaction.c index b1603b9..1c35e34 100644 --- a/05/musl-0.6.0/src/signal/sigaction.c +++ b/05/musl-0.6.0/src/signal/sigaction.c @@ -42,4 +42,12 @@ int __sigaction(int sig, const struct sigaction *sa, struct sigaction *old) return __libc_sigaction(sig, sa, old); } -weak_alias(__sigaction, sigaction); +int sigaction(int sig, const struct sigaction *sa, struct sigaction *old) +{ + if (sig == SIGCANCEL || sig == SIGSYSCALL) { + errno = EINVAL; + return -1; + } + return __libc_sigaction(sig, sa, old); +} + diff --git a/05/musl-0.6.0/src/signal/sigprocmask.c b/05/musl-0.6.0/src/signal/sigprocmask.c index e89f876..a8a4a87 100644 --- a/05/musl-0.6.0/src/signal/sigprocmask.c +++ b/05/musl-0.6.0/src/signal/sigprocmask.c @@ -19,5 +19,26 @@ int __sigprocmask(int how, const sigset_t *set, sigset_t *old) return __libc_sigprocmask(how, set, old); } -weak_alias(__sigprocmask, sigprocmask); -weak_alias(__sigprocmask, pthread_sigmask); +int sigprocmask(int how, const sigset_t *set, sigset_t *old) +{ + sigset_t tmp; + /* Quickly mask out bits 32 and 33 (thread control signals) */ + if (0 && how != SIG_UNBLOCK && (set->__bits[4/sizeof *set->__bits] & 3UL<<(32&8*sizeof *set->__bits-1))) { + tmp = *set; + set = &tmp; + tmp.__bits[4/sizeof *set->__bits] &= ~(3UL<<(32&8*sizeof *set->__bits-1)); + } + return __libc_sigprocmask(how, set, old); +} + +int pthread_sigmask(int how, const sigset_t *set, sigset_t *old) +{ + sigset_t tmp; + /* Quickly mask out bits 32 and 33 (thread control signals) */ + if (0 && how != SIG_UNBLOCK && (set->__bits[4/sizeof *set->__bits] & 3UL<<(32&8*sizeof *set->__bits-1))) { + tmp = *set; + set = &tmp; + tmp.__bits[4/sizeof *set->__bits] &= ~(3UL<<(32&8*sizeof *set->__bits-1)); + } + return __libc_sigprocmask(how, set, old); +} diff --git a/05/musl-0.6.0/src/stdio/clearerr.c b/05/musl-0.6.0/src/stdio/clearerr.c index 3bf94d3..a409120 100644 --- a/05/musl-0.6.0/src/stdio/clearerr.c +++ b/05/musl-0.6.0/src/stdio/clearerr.c @@ -7,4 +7,10 @@ void clearerr(FILE *f) FUNLOCK(f); } -weak_alias(clearerr, clearerr_unlocked); +void clearerr_unlocked(FILE *f) +{ + FLOCK(f); + f->flags &= ~(F_EOF|F_ERR); + FUNLOCK(f); +} + diff --git a/05/musl-0.6.0/src/stdio/feof.c b/05/musl-0.6.0/src/stdio/feof.c index f2b739b..9038a7c 100644 --- a/05/musl-0.6.0/src/stdio/feof.c +++ b/05/musl-0.6.0/src/stdio/feof.c @@ -7,4 +7,7 @@ int feof(FILE *f) return !!(f->flags & F_EOF); } -weak_alias(feof, feof_unlocked); +int feof_unlocked(FILE *f) +{ + return !!(f->flags & F_EOF); +} diff --git a/05/musl-0.6.0/src/stdio/ferror.c b/05/musl-0.6.0/src/stdio/ferror.c index f535fbe..2c59172 100644 --- a/05/musl-0.6.0/src/stdio/ferror.c +++ b/05/musl-0.6.0/src/stdio/ferror.c @@ -7,4 +7,7 @@ int ferror(FILE *f) return !!(f->flags & F_ERR); } -weak_alias(ferror, ferror_unlocked); +int ferror_unlocked(FILE *f) +{ + return !!(f->flags & F_ERR); +} diff --git a/05/musl-0.6.0/src/stdio/fgetc.c b/05/musl-0.6.0/src/stdio/fgetc.c index 3a7f1e3..8810f35 100644 --- a/05/musl-0.6.0/src/stdio/fgetc.c +++ b/05/musl-0.6.0/src/stdio/fgetc.c @@ -8,3 +8,12 @@ int fgetc(FILE *f) FUNLOCK(f); return c; } + +int fgetc_unlocked(FILE *f) +{ + int c; + FLOCK(f); + c = f->rpos < f->rstop ? *f->rpos++ : __uflow(f); + FUNLOCK(f); + return c; +} diff --git a/05/musl-0.6.0/src/stdio/fgets.c b/05/musl-0.6.0/src/stdio/fgets.c index 7939303..22dab95 100644 --- a/05/musl-0.6.0/src/stdio/fgets.c +++ b/05/musl-0.6.0/src/stdio/fgets.c @@ -31,4 +31,7 @@ char *fgets(char *s, int n, FILE *f) return (p == s) ? 0 : s; } -weak_alias(fgets, fgets_unlocked); + +char *fgets_unlocked(char *s, int n, FILE *f) { + return fgets(s, n, f); +} diff --git a/05/musl-0.6.0/src/stdio/fileno.c b/05/musl-0.6.0/src/stdio/fileno.c index 9ffb26d..38bc8e8 100644 --- a/05/musl-0.6.0/src/stdio/fileno.c +++ b/05/musl-0.6.0/src/stdio/fileno.c @@ -5,4 +5,7 @@ int fileno(FILE *f) return f->fd; } -weak_alias(fileno, fileno_unlocked); +int fileno_unlocked(FILE *f) +{ + return f->fd; +} diff --git a/05/musl-0.6.0/src/stdio/fputc.c b/05/musl-0.6.0/src/stdio/fputc.c index ec85938..3e0f738 100644 --- a/05/musl-0.6.0/src/stdio/fputc.c +++ b/05/musl-0.6.0/src/stdio/fputc.c @@ -8,3 +8,12 @@ int fputc(int c, FILE *f) FUNLOCK(f); return c; } + +int fputc_unlocked(int c, FILE *f) +{ + FLOCK(f); + if (c != f->lbf && f->wpos + 1 < f->wend) *f->wpos++ = c; + else c = __overflow(f, c); + FUNLOCK(f); + return c; +} diff --git a/05/musl-0.6.0/src/stdio/fputs.c b/05/musl-0.6.0/src/stdio/fputs.c index e6bdb20..5f78ca7 100644 --- a/05/musl-0.6.0/src/stdio/fputs.c +++ b/05/musl-0.6.0/src/stdio/fputs.c @@ -7,4 +7,9 @@ int fputs(const char *s, FILE *f) return (int)fwrite(s, l, 1, f) - 1; } -weak_alias(fputs, fputs_unlocked); +int fputs_unlocked(const char *s, FILE *f) +{ + size_t l = strlen(s); + if (!l) return 0; + return (int)fwrite(s, l, 1, f) - 1; +} diff --git a/05/musl-0.6.0/src/stdio/fread.c b/05/musl-0.6.0/src/stdio/fread.c index 0fa0b2a..8b9ca55 100644 --- a/05/musl-0.6.0/src/stdio/fread.c +++ b/05/musl-0.6.0/src/stdio/fread.c @@ -46,4 +46,6 @@ eof: return (len-l)/size; } -weak_alias(fread, fread_unlocked); +size_t fread_unlocked(void *destv, size_t size, size_t nmemb, FILE *f) { + return fread(destv, size, nmemb, f); +} diff --git a/05/musl-0.6.0/src/stdio/fwrite.c b/05/musl-0.6.0/src/stdio/fwrite.c index 23974fe..d6bf314 100644 --- a/05/musl-0.6.0/src/stdio/fwrite.c +++ b/05/musl-0.6.0/src/stdio/fwrite.c @@ -48,4 +48,12 @@ size_t fwrite(const void *src, size_t size, size_t nmemb, FILE *f) return l/size; } -weak_alias(fwrite, fwrite_unlocked); +size_t fwrite_unlocked(const void *src, size_t size, size_t nmemb, FILE *f) +{ + size_t l = size*nmemb; + if (!l) return l; + FLOCK(f); + l = __fwritex(src, l, f); + FUNLOCK(f); + return l/size; +} diff --git a/05/musl-0.6.0/src/string/strdup.c b/05/musl-0.6.0/src/string/strdup.c index dd5f80c..defd559 100644 --- a/05/musl-0.6.0/src/string/strdup.c +++ b/05/musl-0.6.0/src/string/strdup.c @@ -10,4 +10,10 @@ char *__strdup(const char *s) return memcpy(d, s, l+1); } -weak_alias(__strdup, strdup); +char *strdup(const char *s) +{ + size_t l = strlen(s); + char *d = malloc(l+1); + if (!d) return NULL; + return memcpy(d, s, l+1); +} diff --git a/05/musl-0.6.0/src/syscall56.s b/05/musl-0.6.0/src/syscall.s index dc81733..67af412 100644 --- a/05/musl-0.6.0/src/syscall56.s +++ b/05/musl-0.6.0/src/syscall.s @@ -1,6 +1,18 @@ +# this file is necessary because tcc doesn't like musl's inline-assembly implementation +# of syscall +.global syscall0 +.global syscall1 +.global syscall2 +.global syscall3 +.global syscall4 .global syscall5 .global syscall6 +syscall0: +syscall1: +syscall2: +syscall3: +syscall4: syscall5: syscall6: # SysV calling convention: RDI, RSI, RDX, RCX, R8, R9, 8(%rsp) @@ -13,4 +25,6 @@ syscall6: mov %r9, %r8 mov 8(%rsp), %r9 syscall + mov %rax, %rdi + call __syscall_ret ret diff --git a/05/musl-0.6.0/src/time/clock_gettime.c b/05/musl-0.6.0/src/time/clock_gettime.c index dab09d5..67a05ba 100644 --- a/05/musl-0.6.0/src/time/clock_gettime.c +++ b/05/musl-0.6.0/src/time/clock_gettime.c @@ -5,3 +5,8 @@ int clock_gettime(clockid_t clk, struct timespec *ts) { return syscall2(__NR_clock_gettime, clk, (long)ts); } + +int clock_settime(clockid_t clk, const struct timespec *ts) +{ + return syscall2(__NR_clock_settime, clk, (long)ts); +} |