Commit Graph

1687 Commits

Author SHA1 Message Date
Philip
8d44851d65 Fix zero-length struct/union test. Remove nonsensical test.
The comment suggests this was meant to detect unions, but in fact it
compared f->c, the union/struct size, against f->next->c, the first
element's offset.

This affected only zero-length structs/unions with a first (zero-length)
element, as in this code:

    struct u2 {
    };

    struct u {
      struct u2 u2;
    } u;

    struct u f(struct u x)
    {
      return x;
    }

However, such structures turned out to be broken anyway, as code like this
was generated for the above f:

0000000000000000 <f>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 81 ec 10 00 00 00    sub    $0x10,%rsp
   b:   66 0f d6 45 f8          movq   %xmm0,-0x8(%rbp)
  10:   66 0f 6e 45 f8          movd   -0x8(%rbp),%xmm0
  15:   e9 00 00 00 00          jmpq   1a <f+0x1a>
  1a:   c9                      leaveq
  1b:   c3                      retq
2015-04-25 19:25:23 +00:00
Philip
1dd3f88f3b x86_64 ABI tests, which currently cause failures
With the x86_64 Linux ELF ABI, we're currently failing two of these
three tests, which have been disabled for now.  The problem is mixed
structures such as struct { double x; char c; }, which the x86_64 ABI
specifies are to be passed/returned in one integer register and one SSE
register; our current approach, marking the structure as VT_QLONG or
VT_QFLOAT, fails in this case.

(It's possible to fix this by getting rid of VT_QLONG and VT_QFLOAT
entirely as at https://github.com/pipcet/tinycc, but the changes aren't
properly isolated at present. Anyway, there might be a less disruptive
fix.)
2015-04-25 18:51:26 +00:00
seyko
9cbab3630e a test for the #pragma push/pop_macro 2015-04-25 15:03:50 +03:00
grischka
72e8ff11e9 tccpp: alternative #pragma push/pop_macro
using next_nomacro() so that for example
    #define push_macro foobar
does not affect how the pragma works (same behavior
as gcc, albeit not MS's cl).
2015-04-23 23:27:36 +02:00
grischka
7c27186a83 Revert "* and #pragma pop_macro("macro_name")"
- pop_macro incorrect with initially undefined macro
- horrible implementation (tcc_open_bf)
- crashes eventually (abuse of Sym->prev_tok)

- the (unrelated) asm_label part is the opposite of a fix
  (Despite of its name this variable has nothing to do with
  the built-in assembler)

This reverts commit 0c8447db79.
2015-04-23 23:26:46 +02:00
Philip
059aea5d35 fix a subtle x86-64 calling bug
I ran into an issue playing with tinycc, and tracked it down to a rather
weird assumption in the function calling code. This breaks only when
varargs and float/double arguments are combined, I think, and only when
calling GCC-generated (or non-TinyCC, at least) code. The problem is we
sometimes generate code like this:

804a468: 4c 89 d9 mov %r11,%rcx
804a46b: b8 01 00 00 00 mov $0x1,%eax
804a470: 48 8b 45 c0 mov -0x40(%rbp),%rax
804a474: 4c 8b 18 mov (%rax),%r11
804a477: 41 ff d3 callq *%r11

for a function call. Note how $eax is first set to the correct value,
then clobbered when we try to load the function pointer into R11. With
the patch, the code generated is:

804a468: 4c 89 d9 mov %r11,%rcx
804a46b: b8 01 00 00 00 mov $0x1,%eax
804a470: 4c 8b 5d c0 mov -0x40(%rbp),%r11
804a474: 4d 8b 1b mov (%r11),%r11
804a477: 41 ff d3 callq *%r11

which is correct.

This becomes an issue when get_reg(RC_INT) is modified not always to
return %rax after a save_regs(0), because then another register (%ecx,
say) is clobbered, and the function passed an invalid argument.

A rather convoluted test case that generates the above code is
included. Please note that the test will not cause a failure because
TinyCC code ignores the %rax argument, but it will cause incorrect
behavior when combined with GCC code, which might wrongly fail to save
XMM registers and cause data corruption.
2015-04-23 18:08:28 +00:00
Philip
aacf65bbfa Bugfix: 32-bit vs 64-bit bug in x86_64-gen.c:gcall_or_jmp
Verify an immediate value fits into 32 bits before jumping to it/calling
it with a 32-bit immediate operand. Without this fix, code along the
lines of

  ((int (*)(const char *, ...))140244834372944LL)("hi\n");

will fail mysteriously, even if that decimal constant is the correct
address for printf.

See https://github.com/pipcet/tinycc/tree/bugfix-1
2015-04-23 17:30:16 +00:00
seyko
b08ce88082 "#pragma once" implementation 2015-04-21 15:46:29 +03:00
seyko
0c8447db79 * and #pragma pop_macro("macro_name")
* give warning if pragma is unknown for tcc
    * don't free asm_label in sym_free(),
      it's a job of the asm_free_labels().

    The above pragmas are used in the mingw headers.
    Thise pragmas are implemented in gcc-4.5+ and current
    clang.
2015-04-21 06:34:35 +03:00
Ramsay Jones
5e8fb713c4 add missing test from -fdollar-in-identifiers commit
Commit 5ce2154c ("-fdollar-in-identifiers addon", 20-04-2015) forgot
to include the test files from Daniel's patch.

Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
2015-04-20 12:03:45 +01:00
seyko
5ce2154c74 -fdollar-in-identifiers addon
* disable a -fdollar-in-identifiers option in assembler files
    * a test is added

    This is a patch addon from Daniel Holden.
2015-04-20 03:44:08 +03:00
Thomas Preud'homme
9336fa7ae5 Fix program symbols exported in dynsym section
Prior to this commit TinyCC was exporting symbols defined in programs
only when they resolve an undefined symbol of a library. However, the
expected behavior (see --export-dynamic in GNU ld manpage) is that all
symbols used by libraries and defined by a program should be exported in
dynsym section. This is because symbol resolution search first in
program and then in libraries, thus allowing program symbol to interpose
symbol defined in a library.
2015-04-18 15:34:04 +08:00
seyko
b472d53672 clarify error message when library not found
a prior error message: cannot find 'program_resolve_lib'
    after a patch: cannot find library 'libprogram_resolve_lib'
2015-04-16 07:30:24 +03:00
Steven G. Messervey
aeaff94ec1 implement #pragma comment(lib,...) 2015-04-15 22:56:21 -04:00
Steven G. Messervey
e50d68e417 Revert "implement #pragma comment(lib,...)"
This reverts commit 8615bb40fb.

Reverting as it breaks on MinGW targets
2015-04-15 21:24:15 -04:00
Steven G. Messervey
8615bb40fb implement #pragma comment(lib,...) 2015-04-15 17:00:26 -04:00
seyko
a13f183e4c ability to compile multiple *.c files with -c switch
Usage example: tcc -c -xc ex5.cgi -xn ex2.c ex7.c ex6.cgi
2015-04-12 15:39:48 +03:00
seyko
0536407204 ability to specify a type of the input file with the -x switch
Usage example: tcc -xc ex5.cgi
    From a gcc docs:

    You can specify the input language explicitly with the -x option:

    -x language
    Specify explicitly the language for the following input files
    (rather than letting the compiler choose a default based on the file
    name suffix). This option applies to all following input files until
    the next -x option. Possible values for language are:

        c  c-header  c-cpp-output
        c++  c++-header  c++-cpp-output
        objective-c  objective-c-header  objective-c-cpp-output
        objective-c++ objective-c++-header objective-c++-cpp-output
        assembler  assembler-with-cpp
        ada
        f77  f77-cpp-input f95  f95-cpp-input
        java

    -x none
    Turn off any specification of a language, so that subsequent files
    are handled according to their file name suffixes (as they are if -x
    has not been used at all)
2015-04-12 15:35:37 +03:00
seyko
dcb36587b5 -fdollar-in-identifiers switch which enables '$' in identifiers
library Cello: http://libcello.org/ which uses `$` and several
    variations of as macros.

    There is also RayLanguage which also uses it as a macro for a kind of
    ObjC style message passing: https://github.com/kojiba/RayLanguage

    This is a patch from Daniel Holden.
2015-04-12 15:32:03 +03:00
seyko
e8ad336ac5 A new file CodingStyle with rules for indentation 2015-04-12 09:26:28 +03:00
seyko
e7a60e4d01 replace a method to force bcheck.o linking
* define __bound_init as external_global_sym insteed of the compiling
      a tiny program
    * remove warning about buf[] when CONFIG_TCC_BCHECK is not defined
2015-04-12 04:47:15 +03:00
seyko
4bb9dd44f1 Fix for Microsoft compilers
Correction for the commit db08122d31
    As pointed Thomas Preud'homme buf[] may be used outside of the block
    whit code:
        name = block;
2015-04-11 16:22:34 +03:00
seyko
5c9dde7255 option to use an old algorithm of the array in struct initialization
This is for a case when no '{' is used in the initialization code.
    An option name is -fold-struct-init-code. A linux 2.4.26 can't
    find initrd when compiled with a new algorithm.
2015-04-10 23:44:10 +03:00
seyko
92efee6e52 fix "handle a -s option" commit
for targets which don't support variable length arrays.
2015-04-10 17:35:54 +03:00
seyko
d81611b641 fix a preprocessor for .S
Lets assume that in *.S files a preprocessor directive
    follow '#' char w/o spaces between. Otherwise there is
    too many problems with the content of the comments.
2015-04-10 16:53:29 +03:00
seyko
8037a1ce39 fix a preprocessor for .S
A test program (tcc -E test.S):
      # .. or else we have a high. This is a test.S
2015-04-10 16:40:30 +03:00
seyko
70dbe169b2 fix a preprocessor for .S
* tell a right line number in error message
      if a #line directive is wrong

    * don't print an error message if we preprocess a .S file
      and #line directive is wrong. This is the case of
      the
        # 4026 bytes
      comment in *.S file.

    * preprocess_skip: skip a line with
	    if (parse_flags & PARSE_FLAG_ASM_COMMENTS)
       		p = parse_line_comment(p);
      if line starts with # and a preprocessor command not found.

      A test program:
      #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
	# This repeats until either a device doesn't exist, or until
      #endif

    * remove a second definition of the TOK_FLAG_* and PARSE_FLAG_*
      from the tccpp.c
2015-04-10 16:31:12 +03:00
seyko
559675b90a a bounds checking code for the ARCH=x86_64 2015-04-10 15:17:22 +03:00
seyko
e92dc595cd Add a demo.bat file to the examples directory on Windows
And a new console demo program: taxi and passengers simulator
2015-04-10 07:46:04 +03:00
seyko
7e7e6148fd fix installation amd bcheck for Windows
* define targetos=Windows when --enable-tcc32-mingw, --enable-cygwin, ...
    * use TARGETOS insteed HOST_OS when selecting PROGS
    * use "$(tccdir)" insteed $(tccdir) on install (spaces in path)
    * install tcc.exe too
    * produce bcheck.o when cross-compiling too (lib/Makefile)
    * force bcheck.o linking by compiling inside tcc_set_output_type()
      a dummy program with local array. Otherwise bcheck.o may be not linked.
    * replace %xz format specifier with %p in bcheck (don't supported on
      Windows)
    * call a __bound_init when __bound_ptr_add, __bound_ptr_indir,
      __bound_new_region, __bound_delete_region called.
      This is because a __bound_init inside ".init" section is not called
      on Windows for unknown reason.
    * print on stderr a message when an illegal pointer is returned:
        there is no segmentation violation on Windows for a program
        compiled with "tcc -b"
    * remove "C:" subdir on clean if $HOST_OS = "Linux"
    * default CFLAGS="-Wall -g -O0" insteed CFLAGS="-Wall -g -O2"
      to speed up compilation and more precise debugging.
2015-04-10 07:37:31 +03:00
seyko
5cd4393a54 handle a -s option by executing sstrip/strip program 2015-04-10 06:53:48 +03:00
seyko
089ce6235c output all sections if we produce an executable file
tcc w/o -g option generate an executable file which format
    is not recognized by binutils. It is like stripped one but
    binutils don't think so. Solution: generate not stripped
    file which can be correctly stripped by external utils.

    may be there is a need to handle a -s option and call
    a sstrip/strip program to do a job.
2015-04-10 06:49:24 +03:00
seyko
3c372b4c8a remove a compilation warnings for libtest and test3
------------ libtest ------------
    ./libtcc_test lib_path=..
    <string>:11: warning: implicit declaration of function 'printf'
    <string>:13: warning: implicit declaration of function 'add'
    ------------ test3 ------------
    tcctest.c:1982: warning: implicit declaration of function 'putchar'
    tcctest.c:2133: warning: implicit declaration of function 'strlen'
2015-04-10 06:44:34 +03:00
seyko
dec959358a fix the bug #31403: parser bug in structure
- a warning: unnamed struct/union that defines no instances
    - allow a nested named struct declaration w/o identifier
      only when option -fms-extensions is used
2015-04-10 06:31:58 +03:00
Raphael Cohn
9fc3d66f1b Fix to accommodate missing i386/bcheck.o during install on Mac OS X 2015-04-07 16:34:37 +01:00
Raphael Cohn
aa6946b92c Fix to test for HOST_OS not TARGETOS 2015-04-07 16:06:43 +01:00
Raphael Cohn
50fc86a447 Fixing bug for Linux x86_64 introduced in previous macosx commit 2015-04-07 15:55:41 +01:00
Raphael Cohn
2ba7542e4b Adjusted configure host_os to use uname for Darwin
Adjusted Makefile to make it Darwin (Mac OS X 10.10)-friendly for cross-compilers
by removing the creation of arm64 cross-compilers on this platform.
2015-04-07 15:44:54 +01:00
Raphael Cohn
fa0eff949d Adjusted configure to be more BSD friendly 2015-04-07 15:18:34 +01:00
seyko
96debc72f8 a small revers for bcheck.o changes (d80593bc4d)
replacing (addr > e->size) with (addr >= e->size)
    was correct only in one place, a second replacing
    is reversed by this commit.
2015-03-30 06:15:47 +03:00
seyko
db08122d31 Fix for Microsoft compilers
Miccrosoft Visual Sudio (Express) 2008 and 2010 do not accept variable
    definitions C99 style, reported by Fabio <oldfaber@gmail.com>
2015-03-29 11:52:16 +03:00
seyko
d80593bc4d fix for the bcheck.o (bug #14958)
- care about __attribute__ redefinition in the system headers
    - an invalid pointer must be returned when (addr >= e->size),
      and not (addr > e->size)

    A test program:
    #include <stdio.h>
    #include <stdlib.h>
    int main ()
    {
	int v[10];
	fprintf(stderr, "&v[0]  = %p\n", &v[0]);
	fprintf(stderr, "&v[10] = %p\n", &v[10]);
	exit(1);
	return 0;
    }
    // tcc -b test.c

    The output before a patch:
    &v[0]  = 0xbf929d8c
    &v[10] = 0xbf929db4

    The output after a patch:
    &v[0]  = 0xbff6e33c
    &v[10] = 0xfffffffe
2015-03-29 11:28:02 +03:00
seyko
f2cfc07554 fix: try to add a bounds.o only if __bounds_init not found
/usr/local/lib/tcc/i386/bcheck.o: error: '__bound_error_msg' defined twice
    #include <stdio.h>
    int main ()
    {
        #if 1
    	    int v[10];
            v[10] = 0;
            fprintf(stderr, "is bounds error catched?\n");
        #endif
        return 0;
    }
    // tcc -b test.c
2015-03-28 19:41:01 +03:00
seyko
3b7f5008fd fix for the previous commit (compilation on RPi) 2015-03-26 11:28:11 +03:00
seyko
acef4ff244 make a bound checking more compatible with Windows 64
On Linux 32:   sizeof(long)=32 == sizeof(void *)=32
    on Linux 64:   sizeof(long)=64 == sizeof(void *)=64
    on Windows 64: sizeof(long)=32 != sizeof(void *)=64
2015-03-26 07:47:45 +03:00
seyko
548a55eda5 fix for the previous commit: tcc_add_support() was used before definition 2015-03-26 06:22:37 +03:00
seyko
a105837aae fix: enforce bcheck.o linking when -b option is used
fixes a crash for the empry program (tcc -b empty.c)
    empty.c: int main() { return 0; }
2015-03-26 06:04:36 +03:00
seyko
cde79a805e fix a bug #43984: tcc -run reports errno=2
The following program (errno.c) reports errno=2 when run
    using "tcc -run errno.c"

    #include <errno.h>
    #include <stdio.h>
    int main(void) { printf("errno=%d\n", errno); return 0; }
2015-03-25 13:26:11 +03:00
seyko
724425addf fix for a -dumpversion option: move it before -dD
Options must be sorted and a long one must preceed a short one.
What was before:
    tcc -dumpversion
    tcc: error: invalid option -- '-dumpversion'
2015-03-23 20:58:27 +03:00
seyko
8f6390061d fix for: x86_64-tcc compiled by i386-tcc is wrong
A test program (must be compiled by the above version of the tcc):

    /* Tickle a bug in TinyC on 64-bit systems:
     * the LSB of the top word or ARGP gets set
     * for no obvious reason.
     *
     * Source: a legacy language interpreter which
     * has a little stack / stack pointer for arguments.
     *
     * Output is: 0x8049620 0x10804961c
     * Should be: 0x8049620 0x804961c
     */
    #include <stdio.h>
    #define NARGS 20000
    int ARG[NARGS];
    int *ARGSPACE = ARG;
    int *ARGP = ARG - 1;
    main() { printf("%p %p\n", ARGSPACE, ARGP); }
2015-03-23 19:24:55 +03:00