Dear TinyCC devs, I am using TinyCC as a component of my asmc project[1], whose main aim is to develop a bootstrapping operating system. Basically of this OS is that at boot time there is only a minimal amount of compiled binary code (called the "seed", currently around 15 KB for asmc). All the rest of the system is provided in source code form, and the binary seed contains just enough code to compile some of the source code, to obtain a more powerful compiler, which can then be used to compile more of the source code, and so on. Ideally, and in the far future, the idea is that at the end of all this chain one has a working copy of Linux, with all the userspace tools (and, yes, compilers!), without feeding to the computer nothing more than the initial small binary seed (and the computer firmware, unfortunately; removing this dependency would be nice, but it's a future goal).
[1] https://gitlab.com/giomasce/asmc/ As I said, currently TinyCC appears in this chain of compilers, since it is an ideal component for this approach: it is written in rather simple C, it is just one program (as opposed as a suite of many different and complicated programs like GCC), but it supports in turn many of the things that GCC supports, and the libtcc.h API is very useful and nice! In order to fit TinyCC in asmc, I had to patch it a little bit. Many changes are probably not fit for upstream tcc, but some might be. Since I am here for the first time, I do not want to commit to mob without having your approval first. In particular, for the moment I submit these two changes to your attention: 1) The usage of read() in tccelf.c is wrong: the return result is nearly never checked, so short reads go undetected. The attached patch fixes this bug by recalling read() whenever needed. It must be pointed out that my patch does not close all the bugs, because errors are still not detected in most cases. But still there is an improvement, because at least read()-s are correct even when short. The patch can also be seen at [2]. [2] https://gitlab.com/giomasce/tinycc/commit/f6be0d483b29e669164565ee5f36f464991b3357 2) I patched TinyCC so that it can be built by a compiler that does not support floating point numbers (as is the case for the C compiler in asmc that builds TinyCC). Basically I import in the TinyCC repository the code from the Berkeley SoftFloat library[3] and replace each operation between floating point numbers with the corresponding call to SoftFloat. SoftFloat is licensed under a permissive BSD-style license, so it should pose no problems to be linked with TinyCC. I also had to take some code from musl (mainly to implement strtod and variants), which is licensed under a MIT license. [3] http://www.jhauser.us/arithmetic/SoftFloat.html In its current form the SoftFloat patch is totally not acceptable for inclusion in mob. It is quite messy and I doubt it works properly for non-Intel architectures. However, before fixing it up I would like to know what is your opinion on including this feature in TinyCC. If would definitely bring in a lot of new code, which might be against the KISS philosophy that TinyCC has. On the other side it would make it possible to emulate the correct floating point behaviour of the target even when cross compiling (SoftFloat also has specific code for emulating ARM behaviour, although I am not really sure what changes from Intel to ARM), which is listed in TinyCC's TODO file[4] (although I believe that file is pretty old, and I am not sure it reflects the project's current priorities). [4] https://repo.or.cz/tinycc.git/blob/acac38afb2c97e21bf1b0aa3262081d027ea3668:/TODO#l30 So I would like to hear what you think on this. Keep in mind that the SoftFloat patch does not modify the generated code, which still uses the floating point opcodes. The change is only in the compiler itself. I am not attaching the whole patch, because it would be uselessly large. You can find it in my repository[5], if you want. In order to test it, compile with "--extra-cflags=-DUSE_SOFTFLOAT". tcc should work as before, but without using floating point instructions. [5] https://gitlab.com/giomasce/tinycc/tree/softfloat Thanks for reading and for working on TinyCC, and please let me know what you think of my patches. Giovanni. -- Giovanni Mascellani <g.mascell...@gmail.com> Postdoc researcher - Université Libre de Bruxelles
From f6be0d483b29e669164565ee5f36f464991b3357 Mon Sep 17 00:00:00 2001 From: Giovanni Mascellani <g...@debian.org> Date: Sun, 13 Jan 2019 10:29:25 +0100 Subject: [PATCH] Fix read() usage in tccelf.c. read() is allowed to short-read, and return less bytes then requested. The caller must restart read() when this happens (and they want more bytes). This patch is still buggy, because errors are not always checked. Still, less buggy than before. --- tccelf.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/tccelf.c b/tccelf.c index 9f242b8..0a5ba71 100644 --- a/tccelf.c +++ b/tccelf.c @@ -2246,13 +2246,25 @@ LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename) return ret; } +ssize_t full_read(int fd, void *buf, size_t count) { + char *cbuf = buf; + size_t rnum = 0; + while (1) { + ssize_t num = read(fd, cbuf, count-rnum); + if (num < 0) return num; + if (num == 0) return rnum; + rnum += num; + cbuf += num; + } +} + static void *load_data(int fd, unsigned long file_offset, unsigned long size) { void *data; data = tcc_malloc(size); lseek(fd, file_offset, SEEK_SET); - read(fd, data, size); + full_read(fd, data, size); return data; } @@ -2265,7 +2277,7 @@ typedef struct SectionMergeInfo { ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h) { - int size = read(fd, h, sizeof *h); + int size = full_read(fd, h, sizeof *h); if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) { if (h->e_type == ET_REL) return AFF_BINTYPE_REL; @@ -2434,7 +2446,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, unsigned char *ptr; lseek(fd, file_offset + sh->sh_offset, SEEK_SET); ptr = section_ptr_add(s, size); - read(fd, ptr, size); + full_read(fd, ptr, size); } else { s->data_offset += size; } @@ -2606,7 +2618,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize) ElfW(Sym) *sym; data = tcc_malloc(size); - if (read(fd, data, size) != size) + if (full_read(fd, data, size) != size) goto fail; nsyms = entrysize == 4 ? get_be32(data) : get_be64(data); ar_index = data + entrysize; @@ -2650,10 +2662,10 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte) unsigned long file_offset; /* skip magic which was already checked */ - read(fd, magic, sizeof(magic)); + full_read(fd, magic, sizeof(magic)); for(;;) { - len = read(fd, &hdr, sizeof(hdr)); + len = full_read(fd, &hdr, sizeof(hdr)); if (len == 0) break; if (len != sizeof(hdr)) { @@ -2706,7 +2718,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) const char *name, *soname; DLLReference *dllref; - read(fd, &ehdr, sizeof(ehdr)); + full_read(fd, &ehdr, sizeof(ehdr)); /* test CPU specific stuff */ if (ehdr.e_ident[5] != ELFDATA2LSB || -- 2.20.1
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel