R_386_GOT32X can occur in object files assembled by new binutils, and in
particular do appear in glibc startup code (crt*.o). This patch is
modeled after the x86_64 one, handling the new relocation in the same
trivial way.
The introduction of read32le everywhere created a subtle issue, going
from
x = *(int*)p;
to
x = read32le(p);
is not equivalent if x is a larger than 32bit quantity, like an
address on x86_64, because read32le returns an unsigned int. The first
sign extends, the latter zero extends. This broke shared library
creation for gawk. It's enough to amend the case of the above
situation, cases like "write32le(p, read32le(p) +- something)" are okay,
no extensions happen or matter.
R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX can occur in object files
comiled by new binutils. They are not dynamic relocations, so normally
wouldn't be a problem for tcc (one doesn't normally mix object files
created by different compiler/binutils, static archives are so out :)).
If it weren't for the glibc startup code, crt*.o, of course. They now
do contain such relocs --> boom. Handle them in the trivial way.
A CString used to be copied into a token string, which is an int array.
On a 64-bit architecture the pointers were misaligned, so ASan gave
lots of warnings. On a 64-bit architecture that required memory
accesses to be correctly aligned it would not work at all.
The CString is now included in CValue instead.
Some test cases:
#define SE ({ switch (0) { } 0; })
// Should give error:
int x = SE;
void f(void) { static int x = SE; }
void f(void) { enum e { a = SE }; }
void f(void) { switch (0) { case SE: break; } }
// Correct:
int f(void) { return SE; }
int f(void) { return sizeof(SE); }
tcc_normalize_inc_dirs: normally no problem to be absolutly
gcc compatible as long as it can be done the tiny way.
This reverts to the state before recent related commits and
reimplements a (small) part of it to fix the reported problem.
Also: Revert "parsing "..." sequence"
c3975cf27c
&& p[1] == '.'
is not a reliable way to lookahead
- avoid memory allocation by using its (int) token number
- avoid additional function parameter by using Attribute
Also: fix some strange looking error messages
In a case like
typedef int T[1];
const T x;
we must make a copy of the typedef type so that we can add the type
qualifiers to it.
The following code used to give
error: incompatible types for redefinition of 'f'
typedef int T[1];
void f(const int [1]);
void f(const T);
round and fmin/fmax are relatively commonly used functions but were not
implemented anywhere in the tcc Windows distribution package. Newer mingw(64)
math.h stil doesn't include these implementations.
Add C implementations for these functions and place it as inline functions at
win32/include/tcc/tcc_libm.h - which is already included from math.h .
The code is mostly taken from musl-libc rs-1.0 (MIT) [*],
musl-libc: http://git.musl-libc.org/cgit/musl/tree/src/math?h=rs-1.0
license: http://git.musl-libc.org/cgit/musl/tree/COPYRIGHT?h=rs-1.0
Potential enhancements:
- Check how many useful libm implementations are still missing and consider
adding them (some of them already work via the MS runtime).
- Consider putting libm implementations in an actual libm.a file, or add a dummy
one such that build processes which try to link with libm will not fail.
The asm code cannot currently be used with tcc since tcc doesn't support 't'
constraint.
Use inline C implementation instead, place it win32/include/tcc/tcc_libm.h, and
include it from win32/include/math.h.
Since fpclassify now works, it also fixes few other macros which depend on it.
Implicitly fixed: isfinite, isinf, isnan, isnormal.
The implementations were taken from musl-libc rs-1.0 (MIT license).
musl-libc: http://git.musl-libc.org/cgit/musl/tree/src/math?h=rs-1.0
license: http://git.musl-libc.org/cgit/musl/tree/COPYRIGHT?h=rs-1.0
It was broken due to tcc not able to compile asm with 't' constraint, and it's
still broken because fpclassify on which it now depends has the same issue. Next
commit will fix this.