Compare commits

...

3333 Commits

Author SHA1 Message Date
Mounir IDRASSI
a338258d30 Fix qualifiers on const array struct members
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-arm64-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
build and test / test-riscv64-linux-native (push) Waiting to run
Use the existing array-aware qualifier helper when propagating qualifiers from a const or volatile aggregate to a selected field. This keeps address-of array members from spuriously warning while preserving warnings for discarded qualifiers and read-only writes.

Add regression coverage for pointer-to-array returns, array decay, and writes through const array members.
2026-06-13 22:26:02 +09:00
Meng Zhuo
fb4077f2da CI: fix win32 MSVC setup and arm64 test
Replace hardcoded VsDevCmd.bat Enterprise path with vswhere.exe +
vcvarsall.bat for dynamic VS discovery across editions and runner
image versions.  Architecture args: amd64, x86, amd64_arm64.

Split x86_64/i386 win32 jobs into separate build and test steps.

For arm64: keep build+test in one step (needs vcvarsall for lib.exe).
Prepend standalone LLVM bin to PATH so clang targets ARM64 natively
instead of VS's clang-cl inheriting the x64-hosted cross-compile env.
2026-06-12 10:26:51 +08:00
Meng Zhuo
724b24eeb4 riscv64: implement float/double constant loading 2026-06-12 10:26:51 +08:00
Meng Zhuo
d8aee9b26e riscv64: consolidate riscv intrinsics into lib-riscv.c
Replace the single-purpose lib/riscvflush.c with lib/lib-riscv.c
following the lib-arm64.c naming convention.
2026-06-12 10:26:50 +08:00
Meng Zhuo
b8f680a3b4 CI: use RISE runner to test riscv64 2026-06-02 16:47:08 +08:00
Meng Zhuo
1444843fd1 riscv64-link: fix C90 mixed declaration warning
Fix -Wdeclaration-after-statement: move tp_offset declaration
before the for-loop in R_RISCV_TPREL_HI20/LO12_I relocation
handler.
2026-05-31 22:36:41 +08:00
Meng Zhuo
6b53465347 riscv64: enable gen_clear_cache with I-cache flushing
Wire gen_clear_cache to __riscv64_clear_cache builtin, emitting
fence.i for instruction cache synchronization.
Add lib/riscvflush.c to provide __clear_cache for JIT bootstrap.
Extend tccrun.c I-cache flush guard to include RISC-V targets.
Add gen_clear_cache declaration to tcc.h riscv64 section.
2026-05-31 22:36:41 +08:00
Mounir IDRASSI
3b1fe97a59 win32: define arm64 Interlocked helpers in winnt.h
Move the TinyCC/Windows ARM64 Interlocked workaround from the semlock call site into the bundled WinAPI header. This keeps tcc.h using the normal Interlocked API while avoiding unresolved Interlocked imports when tcc -run self-compiles on Windows ARM64.

Update lib/bt-exe.c as well so its ARM64 runtime object does not define a second InterlockedExchange fallback now provided by winnt.h.
2026-05-23 22:39:17 +09:00
Mounir IDRASSI
904e95cbdf win32: avoid Interlocked imports for tcc arm64
Windows/arm64 exposes Interlocked* operations as compiler intrinsics rather than kernel32 exports. When tcc -run self-compiles tcc.c, calls to InterlockedCompareExchange or InterlockedExchange can therefore remain as unresolved imports in the in-memory linker.

Route the TinyCC arm64 path through the existing __atomic helpers while keeping Interlocked* for other Windows compilers. The compile-lock initialization state machine remains unchanged.
2026-05-21 08:41:08 +09:00
Mounir IDRASSI
601a088214 win32: improve tccrun protection diagnostics
Report VirtualProtect failures with a Windows-specific -run diagnostic.
On Win64, also treat RtlAddFunctionTable failure as an error so unwind
registration problems are visible.
2026-05-15 21:41:46 +09:00
Mounir IDRASSI
1a54e47dda pe: add dll characteristic linker options
Add PE linker switches to set and clear DYNAMIC_BASE, NX_COMPAT,
HIGH_ENTROPY_VA and TERMINAL_SERVER_AWARE without changing x86/x64
defaults. HIGH_ENTROPY_VA is limited to 64-bit PE targets and implies
DYNAMIC_BASE; clearing DYNAMIC_BASE also clears HIGH_ENTROPY_VA.

When DYNAMIC_BASE is requested for an executable, emit base relocations
and clear RELOCS_STRIPPED so Windows ASLR can relocate the image. Keep
the existing ARM64 default hardening flags.
2026-05-15 21:40:44 +09:00
Mounir IDRASSI
37b7247796 win32: run cv2pdb without shell quoting issues
Invoke cv2pdb with _spawnvp on Windows so output paths are passed
as argv entries instead of through cmd.exe.

For non-Windows PE cross builds, keep the system() fallback but
shell-quote the executable name and size the PDB path dynamically.
2026-05-15 21:40:43 +09:00
Mounir IDRASSI
6a7c3df4d5 win32: make compile lock initialization thread-safe
Use interlocked state transitions around the lazily initialized Windows
CRITICAL_SECTION so concurrent first-time callers cannot race into a
double initialization.
2026-05-15 21:40:43 +09:00
Meng Zhuo
757507eb02 fix: skip TLS test on osx
tests/tests2/Makefile: skip 144_tls on OSX
2026-05-13 15:31:17 +08:00
Mounir IDRASSI
6728a64f1b win32: use VirtualAlloc for run memory 2026-05-13 14:25:22 +09:00
Meng Zhuo
256b4ef63c fix: TLS test failures on osx/win32/armv7
- tccmacho.c: add STT_TLS to convert_symbol() for Mach-O output
- tests/tests2/Makefile: skip 144_tls on Win32 (no pthread.h) and
  remove arm from TLS arch list (QEMU user-mode cannot emulate
  MRC p15 TLS register access)
2026-05-13 12:28:58 +08:00
Meng Zhuo
8502540b4a feat(i386): add TLS Local Exec code generation and linker relocations 2026-05-13 10:30:10 +08:00
Meng Zhuo
841ce0da03 feat(arm): add TLS Local Exec code generation and linker relocations 2026-05-13 10:29:44 +08:00
Meng Zhuo
8abaf10ab5 feat(arm64): add TLS Local Exec code generation and linker relocations 2026-05-13 09:37:59 +08:00
Meng Zhuo
11f5c6e1f9 feat(riscv64): add TLS Local Exec code generation and linker relocations 2026-05-13 09:37:42 +08:00
Meng Zhuo
ea26b85ac0 feat(x86_64): add TLS Local Exec support with tests 2026-05-13 09:07:31 +08:00
Meng Zhuo
8443e25bf5 feat: implement Thread Local Storage frontend support 2026-05-12 20:59:01 +08:00
inostensibl
fad812360b tccgen: fix void expression side effect regression
From 7e01b20362

reduced from an app that builds/runs with gcc or clang.
2026-05-09 22:11:58 -04:00
Meng Zhuo
2888e49f39 riscv64-gen: implement gen_clear_cache
Emit fence + fence.i (Zifencei extension) for I/D cache
synchronization, needed for tcc -run mode on RISC-V.
Zifencei is required by the RISC-V Linux ABI and present
on all Linux-capable cores, though technically not part
of the RV64G base ISA.
2026-05-07 16:07:53 +08:00
Meng Zhuo
c77339ab41 riscv64: emit .riscv.attributes section in ELF output 2026-05-07 11:44:46 +08:00
Meng Zhuo
7f764f340f riscv64-asm: complete AMO aq/rl suffixes for all ops
Add 48 tokens + handlers + dispatch cases for all AMO aq/rl
variants (amoswap, amoand, amoor, amoxor, amomax, amomaxu,
amomin, amominu; each x {.w,.d} x {.aq,.rl,.aqrl}).

GNU-compatible 2-dot naming via DEF_ASM_WITH_SUFFIXES.
Correct funct5 values: amoswap=0x01, amoand=0x0C, amoor=0x08,
amoxor=0x04, amomax=0x14, amomaxu=0x1C, amomin=0x10, amominu=0x18.

Extend 141_riscv_asm amo_main() with 10 representative aq/rl
variants covering all ops x ordering suffix combinations.

Verified against riscv64-linux-gnu-as 2.44.
2026-05-07 11:44:46 +08:00
Meng Zhuo
a672babc6f tests: fix 141_riscv_asm AMO crash, restore full test coverage
Replace raw-register AMO asm with proper inline-asm constraints
for all three operands (rd, rs2, rs1).  Use long long for .d-word
AMO variants with pre-set values (xd=0xCAFEBABECAFEBABE,
val=0xDEADBEEFDEADBEEF) to avoid uninitialized-data issues.

Restore csr_pseudo_main printf output and re-enable amo_main()
in the test (was commented out as 'crash on qemu').

Use GEN = $(GEN-TCC) since GCC and TCC produce different fcsr
initial values on riscv64.
2026-05-07 11:44:18 +08:00
grischka
44977b0de8 tcctest: restore & combine
Revert 199369bb17
- generating test.ref with tcc makes little sense.
- combine riscv_asm & conversion tests into only two files.
  (too many files are bad ...)
2026-05-06 18:52:01 +02:00
grischka
6daf1617ef configure & tcc.h: include & lib searchpath cleanup
configure:
- remove CONFIG_USE_LIBGCC, --with-libgcc
- remove CONFIG_LDDIR
- remove CONFIG_USR_INCLUDE
- add -q switch for quiet (=no) output

tcc.h:
- remove /usr/local/include&lib search paths

arm-gen.c:
- remove default_elfinterp() function

tccelf.c:
- setup the ELF-interp in tccelf_new()
2026-05-06 13:46:42 +02:00
grischka
923fba83f1 general: long double issues
tccgen.c:
- init_putv(): improve long double cross constants
  now in separate function including some basic conversions

arm-gen.c:
- switch to using TCC_USING_DOUBLE_FOR_LDOUBLE
  now it actually never will see VT_LDOUBLE

lib/lib-arm64.c:
- simplify by using unions

tccpp.c:
- reduce amounts of #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
2026-05-06 13:46:38 +02:00
grischka
7e01b20362 tccgen: void values, etc...
originally, this was meant to avoid 'void' values leak
to the gen-xxx.c generators which would otherwise try
to load void from/to registers.  Also catch invalid types
such as 'unsigned bool' eariler.

tccgen.c:
- expr_cond()/gexpr(): ignore VT_VOID
- gen_cast(): set float reg with static initializers to make
  backends happier with invalid input
- init_putv():
  improve static compound literal initializers
Also:
- ignore "missing prototype" and "might return no value"
  for old style K&R functions

tcc.c, libtcc.c:
- tcc_set_output_type(): return errors from loading crt1.o

tcc.h/tccpp.c:
- fix horrible longstanding mistake with sizeof SValue.tab.
  Must have place for sizeof (long double) rather than the
  target's LDOUBLE_SIZE.

tccdefs.h:
- add a fake __[u]int128_t for all platforms

arm-gen.c:
- gen_cvt_ftof() must load to reg always

arm64-gen.c:
- simplify arm64_pcs() a bit

i386/x86_64-gen.c:
- do not assume char is signed (for cross compilation arm->x86)

tccelf/macho linker message:
- instead of
      "undefined symbol 'X'"
  now say
      "unresolved reference to 'X'"
  which makes it more clear that it is a _linker_error_.

tccasm.c:
- .align/p2align: use 'nop's in exec sections
2026-05-06 13:46:27 +02:00
Meng Zhuo
016087c954 riscv64-asm: implement AMO, fcvt rounding, and fcvt encoding fixes
AMO (A-extension):
  18 base instructions: amoadd/swap/and/or/xor/max/maxu/min/minu .w/.d
  6 aq/rl suffixes: amoadd.w.aq/.rl/.aqrl, amoadd.d.aq/.rl/.aqrl
  Correct funct5 (GNU as verified):
    amoadd=0x00 amoswap=0x01 amoxor=0x04
    amoand=0x0C  amoor=0x08  amomax=0x14
    amomaxu=0x1C amomin=0x10 amominu=0x18
  R-type opcode 0x2F, aq/rl in bits [26:25]

FCVT rounding modes (GNU operand syntax):
  fcvt.w.s rd, rs1 [, rtz/rne/rup] -- optional 3rd operand
  asm_fcvt_opcode() handler with asm_fcvt_rm() helper
  Keywords rne=0, rtz=1, rdn=2, rup=3, rmm=4

FCVT encoding fixes:
  fcvt.s.d: funct7 0x40->0x20
  fcvt.d.s: funct7 0x42->0x21

Tests: 144 CSR, 145 F/D cmp+cvt, 146 AMO, 147 fcvt round.
All verified against riscv64-linux-gnu-as 2.44 on Spacemit X100.
2026-05-06 19:18:17 +08:00
Meng Zhuo
f8011ea9b7 riscv64-asm: implement CSR pseudo-instructions
Add handlers for csrr, csrw, csrwi, csrsi, csrci as pseudo-instructions:
  csrr rd, csr     -> csrrs rd, csr, x0
  csrw csr, rs     -> csrrw x0, csr, rs
  csrwi csr, uimm  -> csrrwi x0, csr, uimm
  csrsi csr, uimm  -> csrrsi x0, csr, uimm
  csrci csr, uimm  -> csrrci x0, csr, uimm

Tokens were already defined in riscv64-tok.h.  Tested on
Spacemit X100 using fcsr (0x003) which is accessible in user mode.
cycle/instret CSRs are privileged and not accessible from Linux
user mode on this hardware.
2026-05-06 18:33:15 +08:00
Meng Zhuo
199369bb17 tests: generate test.ref with TCC instead of host CC
The promote char/short funcret test in tcctest.c invokes
undefined behavior (narrow return without extension). GCC
produces one set of values, TCC with PROMOTE_RET produces
correct ABI-compliant values. Generate the reference with
TCC so self-tests are consistent.
2026-05-06 14:43:30 +08:00
Meng Zhuo
3935c3bb55 riscv64-asm: add basic F/D extension instructions (fadd/fsub/fmul/fdiv)
Adds the 8 most essential floating-point arithmetic instructions:
fadd.s/d, fsub.s/d, fmul.s/d, fdiv.s/d, for both single and double
precision.  These complement the existing fsgnj/fmax/fmin/fsqrt set.
Comparison (feq/flt/fle) and conversion (fcvt) instructions remain
as future work.
2026-05-06 12:30:34 +08:00
Meng Zhuo
273978b927 riscv64-asm: implement pseudo-instructions sext.w, fmv, fneg
sext.w: addiw rd, rs, 0 (sign-extend 32-bit word)
fmv.s/fmv.d: fsgnj.s/d rd, rs, rs (float register move)
fneg.s/fneg.d: fsgnjn.s/d rd, rs, rs (float register negate)

These were defined in riscv64-tok.h but had no handler code.
CSR pseudo-instructions (csrr, csrw, csrci, csrsi, csrwi) skipped
for now — they require CSR operand parsing in binary mode.
2026-05-06 12:30:34 +08:00
Meng Zhuo
2a33daedca tccasm: extend .reloc directive for RISCV64 relocation types
Previously, .reloc unconditionally errored on RISCV64 — only ARM64
had permission to use R_AARCH64_CALL26.  Now supports common RISCV64
relocations: R_RISCV_CALL, CALL_PLT, BRANCH, JAL, PCREL_HI20,
PCREL_LO12_I/S, 32_PCREL, 32, 64.

Restructured to use string-to-reloc-type mapping, shared across all
targets.
2026-05-06 12:30:34 +08:00
Meng Zhuo
3257afa160 riscv64-link: add R_RISCV_RELATIVE case in relocate()
arm64-link.c has R_AARCH64_RELATIVE handling.  Without this case,
incoming R_RISCV_RELATIVE relocations from object files fall through
to the 'FIXME: handle reloc type' default path.

P1.7 (NEED_BUILD_GOT guards) is not needed: NEED_RELOC_TYPE and
NEED_BUILD_GOT are always defined in the build context (tcc.h:1608).
2026-05-06 12:30:34 +08:00
Meng Zhuo
419b527657 riscv64-asm: implement far branches via expansion
For branch targets that are external/static symbols (where the
offset cannot be determined at assembly time), expand to:
  b<inverse> .+8       # skip if condition false
  auipc t0, %pcrel_hi  # load target upper bits
  jalr x0, %pcrel_lo(t0)  # jump

This handles the ±4 KiB B-type limitation without requiring
linker relaxation (R_RISCV_RELAX).  Local immediates within
range still use the compact B-type encoding.
2026-05-06 12:30:34 +08:00
Meng Zhuo
5c2240a896 riscv64-asm: remove long long 'not implemented' errors in inline asm
On RV64, long long (64-bit) fits in a single general-purpose register.
The existing load/store calls already handle 64-bit values correctly.
The 'not implemented' errors were vestigial from 32-bit architectures
where long long requires a register pair.

Removing these errors allows inline asm to accept 64-bit integer operands
on RV64, which is important since this is the native register width.
2026-05-06 12:30:34 +08:00
Meng Zhuo
366569eb7a riscv64-asm: fix neg/negw pseudo-instruction encoding
neg/negw were incorrectly using asm_emit_i (I-type/xori) with an
immediate of 1, producing 'xori rd, rs, 1' instead of the intended
'sub rd, x0, rs'.  Fixed to use asm_emit_r (R-type) with proper
SUB/SUBW opcode (0x33/0x3B, func3=0, func7=0x20).

The old code generated wrong machine code for these pseudo-instructions.
negw now also correctly uses OP-32 (0x3B) for 32-bit subtraction.
2026-05-06 12:30:34 +08:00
Meng Zhuo
ff917c09aa riscv64: implement gen_cvt_sxtw with addiw instruction
Replaces the empty stub that relied on 'RV64 registers are always
sign-extended' assumption.  Now emits addiw rd, rs, 0 for proper
32-to-64 bit sign extension, matching arm64's sxtw behavior.

Verified on Spacemit X100: tests2 pass (125_atomic_misc has a
pre-existing intermittent segfault, not caused by this change).
2026-05-06 12:30:34 +08:00
Meng Zhuo
9f0915a506 riscv64: implement gen_cvt_csti for narrow int promotion
Add sign/zero extension for char/short to int casts using
slli+srai (signed) or slli+srli/andi (unsigned) sequences.
Also adds RISCV64 to the gen_cvt_csti fast-path conditional
in tccgen.c:3466, matching arm64/i386/x86_64.

Verified on Spacemit X100: all tests2 pass, no regressions.
2026-05-06 12:30:34 +08:00
Meng Zhuo
69c8e92566 riscv64: add PROMOTE_RET for narrow return ABI compliance
Other mature backends (i386, x86_64, arm64) all define PROMOTE_RET,
which forces explicit sign/zero extension of narrow return types at the
caller side.  Without it, riscv64 relied on the assumption that RV64
registers are always sign-extended, which may not hold when interfacing
with non-TCC compilers.

Verified on Spacemit X100 (riscv64): self-compilation is self-consistent
across 3 layers.  test3 reference mismatch is expected — the test
intentionally invokes UB via type-punned function pointers (csf macro).
2026-05-06 12:30:34 +08:00
grischka
30afb50e64 arm64-win32 review: fix problems and pass tests
tccpe.c:
- fix arm64 unwind codes (to make native set/longjmp() work)
  sizeof(RUNTIME_FUNCTION) is 8 on arm64 in the first place
  no need to note stack slots if we don't save any registers anyway

arm64-gen.c:
- fix long double reg-move
- fix arm64_hfa() for structs with float arrays
- gfunc_prolog(): setup stackframe eariler (simplifies unwind codes)
- new function gv_addr(RC);

win32/include/setjmp.h:
- provide correct definition for setjmo() (frameoffset = 224)

tccasm.c:
- support ".quad" with symbol & relocation
- support ".size"
- fix ". - symbol" arithmetic

win32/lib/crt1.c and win32/include/stdlib.h:
- do not write to __argc/__argv which reside in msvcrt.dll
  (msvcrt.dll on arm64 does not like that, crashes on unload)

tcc.c,libtcc.c:
- new functions tcc_fopen/fclose to avoid different stdio unstances
  in tcc.exe & libtcc.dll

tests & github workflow:
- add test-win32.bat to run tests with a tcc compiled by build-tcc.bat
- add msvcrt_start.c for gcc/clang to use the same runtime as tcc

  the problem is that newer gcc as well as clang and cl are
  linking to newer runtimes (such as UCRT) that have partially
  different printf format behavior which makes tcctest fail.

  the solution here is to force these compilers to link with
  msvcrt.dll just like tcc.

  Also, there is no gcc on arm64-win32 currently at all.

  Anyway, this approach to running the github CI tests
  does not require msys2.  But It does rely on gnumake
  as well as on some 'sh' shell though which seems to be
  installed somewhere (maybe it is the one from git).
2026-05-04 12:51:10 +02:00
Benjamin Oldenburg
576cd2a923 arm64-win32 support: symbolic op-code constants
from: https://github.com/bold84/tinycc
Author: Benjamin Oldenburg <benjamin.oldenburg@ordis.co.th>  2026-04-04 16:29:28
Committer: Benjamin Oldenburg <benjamin.oldenburg@ordis.co.th>  2026-04-04 16:29:28
Branch: win_arm64_clean
Commit: 8b5ab1bb01

Also here: https://repo.or.cz/tinycc.git/shortlog/refs/mob/mob_bold84/win_arm64_clean

This and the previous commits on mob is selected parts
of that original branch. So it is not everything.

It is not, for example:
- unrelated whitespace changes in many files
- a "pin msvcrt.dll" feature in tccpe.c (why that)
- a native getenv() replacement in tcc.c (why that)
- larger changes to the win32/lib runtime and tccrun.c (not needed)
- a very gcc specific detail for struct alignent in tccgen.c
- a custom set/longjmp implementation/replacement (not needed)
- lots of rather basic test files in the win32 folder
- a 'tests/asm' folder with some files (one file renamed to 140_test...c)
- a .docs folder with one file
2026-05-04 12:50:42 +02:00
Benjamin Oldenburg
44e6853cb1 arm64-win32 support: target PE & varargs 2026-05-04 12:49:53 +02:00
Benjamin Oldenburg
5c728d6506 arm64-win32 support: improve HFA & struct 2026-05-04 12:49:53 +02:00
Benjamin Oldenburg
90d17c9748 arm64-win32 support: use arm64_sub_sp() 2026-05-04 12:49:53 +02:00
Benjamin Oldenburg
99713bcbfa arm64-win32 support: use arm64_sym() 2026-05-04 12:49:53 +02:00
Benjamin Oldenburg
303badef22 arm64-win32 support: fix scaled mask 2026-05-04 12:49:53 +02:00
Benjamin Oldenburg
41bcb4a78f arm64-win32 support : linker & -run 2026-05-04 12:49:53 +02:00
Benjamin Oldenburg
f459aff5f6 arm64-win32 support : arm64 assembler 2026-05-04 12:49:53 +02:00
Benjamin Oldenburg
ea823189d6 arm64-win32 support : tests 2026-05-04 12:49:53 +02:00
Benjamin Oldenburg
03d58b0746 arm64-win32 support : runtime 2026-05-04 12:49:53 +02:00
Benjamin Oldenburg
ff5d3b4874 arm64-win32 support : configure & Makefiles
from: https://github.com/bold84/tinycc
Author: Benjamin Oldenburg <benjamin.oldenburg@ordis.co.th>  2026-04-04 16:29:28
Committer: Benjamin Oldenburg <benjamin.oldenburg@ordis.co.th>  2026-04-04 16:29:28
Branch: win_arm64_clean
Commit: 8b5ab1bb01

Also here: https://repo.or.cz/tinycc.git/shortlog/refs/mob/mob_bold84/win_arm64_clean

This and the followup commits on mob is selected parts
of that original branch. So it is not everything.

It is not, for example:
- unrelated whitespace changes in many files
- a "pin msvcrt.dll" feature in tccpe.c (why that)
- a native getenv() replacement in tcc.c (why that)
- larger changes to the win32/lib runtime and tccrun.c (not needed)
- a very gcc specific detail for struct alignent in tccgen.c
- a custom set/longjmp implementation/replacement (not needed)
- lots of rather basic test files in the win32 folder
- a 'tests/asm' folder with some files (one file renamed to 140_test...c)
- a .docs folder with one file
2026-05-04 12:49:25 +02:00
grischka
d9a6d9aec0 reverts (11/2025 - 04/2026)
Revert "Add support to debug libtcc code"
- not fully developed experimental feature
This reverts commit 1fe3e3bff5.
This reverts commit 4768b11737.

Revert "tests: add test for x86_64 xor REX prefix bug in load()"
- AI generated nonsense test
This reverts commit d5ecb52a71.

Revert "tccpp.c: Improve integer constant overflow warning"
- Too long and confusing messages and comments for feature
  with questionable benefit.
This reverts commit 085bdf8997.

riscv64-link:
- cleanup "pair pcrel lo relocations by hi address"
  From fada98b1ce

tccgen.c:
- Simplify "Cast signed pointer offset to ptrdiff_t before performing arithmetic"
  From 5ad52cc1ed

libtcc.c:
- Revert "tcc options: document behavior and clashes (no-op)"
  a bit more information than one would like to have I think.
  (why try to understand that comments plus the extra
  script if one can as well just read the code itself ;)
  From 234e2dd2bf

tccdefs.h:
- Revert "Move lib/va_list.c into include/tccdefs.h"
  Lets not fill tccdefs.h with too much inline code
  Also, -nostdlib -run is no longer supported
  From fa6a6bfbbd

arm64-gen.c:
- cleanup "Implement TOK_NEG for floats natively"
  Also, make it "no lvalue" in tccgen.c/x86-64-gen.c
  From c39eaf10cf

lib/lib-arm64.c:
- cleanup "Remove libc dependency from lib-arm64"
  using unions is much faster than some made up memcpy()
  From 8c61b91de8
2026-05-03 11:09:45 +02:00
H-language
a66ac623b2 win32: add missing AttachConsole export to kernel32.def
AttachConsole has been exported from kernel32.dll since Windows XP
but was absent from TCC's import definitions, causing
"undefined symbol 'AttachConsole'" at link time for code that uses it.
2026-05-01 09:58:03 +12:00
Cyan Ogilvie
4768b11737 tccrun: fix OOB read in elf_output_obj after tcc_relocate with -g
When -g is set, cleanup_sections() preserves all sections after relocate,
including the SHT_RELX relocation sections. cleanup_symbols() drops all
STB_LOCAL symbols from the symbol table, which renumbers the remaining
globals. The kept relas still hold r_info indices from the pre-cleanup
numbering, but nothing rewrites them. A later elf_output_obj() call ends
up in sort_syms() / update_relocs(), which allocates old_to_new_syms[]
sized for the post-cleanup (smaller) symtab and then indexes it with the
stale (larger) sym_index values from those rela entries, reading past
the end of the array.

Fix: when do_debug is set, build an old->new index map while re-adding
globals, then walk every retained SHT_RELX section linked to the symtab
and rewrite its r_info entries. Locals (and the undef sym at 0) map to
0 by tcc_mallocz, so relocations against dropped locals now refer to
SHN_UNDEF - the best we can do without preserving the locals themselves.

Reproducible with libtcc_debug.c if the program contains enough static
helpers / string literals for the symtab to actually shrink; observed
under valgrind in jitc (https://github.com/cyanogilvie/jitc) when
compiling re2c-generated state machines with -g.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 15:37:49 -03:00
Petr Skocik
b39da9f6fa Fix false warnings with readonly atomics
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
Code like:

    #include <stdatomic.h>
    _Atomic const int ai; int aiGet(void){ return atomic_load(&ai); }

has been raising "warning: assignment of read-only location".

This is due to `__typeof__ (*ptr) tmp;` not rvalue-converting the target
type.
2026-04-28 08:40:53 +02:00
Petr Skocik
5675177b7f allow $ at nonstarting positions in asm symbols under -fdollars-in-identifiers
e.g., asm("foo$bar: ret;");
2026-04-28 08:36:09 +02:00
Reini Urban
543d84c668 .gitignore: Add tests/libtcc_test_xor_rex 2026-04-26 14:56:39 +02:00
Detlef Riekenberg
9b8765d8ba Revert commits from OpenCode-AI and a partial regression fix
This reverts the crap from an unknown committer "OpenCode[AI]", that added an extension to TinyCC,
which is incompatible to the C standard and not available in any other mainstream C compiler:

* Revert "No More ; needed"
This reverts commit 6547ea47d6

* Revert "Add AGENTS.md"
This reverts commit 898f496dc9.

This also reverts a regression fix by "Zuhaitz.dev", which fixed a small part of the OpenCode-AI chaos:
* Revert "tccgen: Fix optional semicolon regression"
This reverts commit 169628a6ab

--
Regards ... Detlef
2026-04-20 01:42:41 +02:00
Anon
7b92d2dcd2 Fix warning 2026-04-16 13:16:17 -07:00
Zuhaitz-dev
169628a6ab tccgen: Fix optional semicolon regression 2026-04-16 17:24:21 +01:00
Cyan Ogilvie
8ecfd0a722 Relicensing TinyCC 2026-04-16 10:45:24 -03:00
Cyan Ogilvie
690fb14015 x86_64-gen: fix missing REX prefix for xor zero into r8-r15
load() used a raw o() call to emit xor-zero which lost bit 3 of the
register number via REG_VALUE():

    o(0xc031 + REG_VALUE(r) * 0x900);

For r >= 8, this emitted the wrong instruction (e.g. xor %ebx,%ebx
for TREG_R11 instead of xor %r11d,%r11d), clobbering the wrong
register.

Use orex() to emit the REX prefix, consistent with all adjacent
branches in load().
2026-04-16 10:42:16 -03:00
Cyan Ogilvie
d5ecb52a71 tests: add test for x86_64 xor REX prefix bug in load()
When load() in x86_64-gen.c generates a zero constant for a 64-bit
register, it uses:

    o(0xc031 + REG_VALUE(r) * 0x900);

REG_VALUE(r) masks to (r & 7), losing bit 3, and no orex() call
emits the REX prefix needed for registers r8-r15.  For TREG_R11
(used by gcall_or_jmp for indirect calls), this emits
"xor %ebx,%ebx" (31 db) instead of "xor %r11d,%r11d" (45 31 db),
clobbering the wrong register.

The test compiles an indirect call through a null function pointer
((void(*)(void))0)() via libtcc, then inspects the generated machine
code for the incorrect encoding.
2026-04-16 10:42:16 -03:00
OpenCode[AI]
6547ea47d6 No more ; needed 2026-04-15 20:56:01 -07:00
OpenCode[AI]
898f496dc9 Add AGENTS.md 2026-04-15 20:28:42 -07:00
Stefan
98765e5ebc libtcc.c: Change parameter name of tcc_set_realloc
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
In libtcc.h there is void tcc_set_realloc(TCCReallocFunc *my_realloc).
Name the parameter in the function definition in libtcc.c accordingly.
2026-03-28 15:44:20 +01:00
Stefan
085bdf8997 tccpp.c: Improve integer constant overflow warning
Improve the warning about an integer constant overflow with the used
overflown value and the potentially aimed value.

This helps spotting the 0 to much in 0x80000000000000000.
2026-03-28 15:31:21 +01:00
diannaaa
fada98b1ce fix(riscv64-link): pair pcrel lo relocations by hi address
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
Track R_RISCV_PCREL_HI20/GOT_HI20 relocations by address and resolve LO12 relocations against the referenced HI, instead of only using the last seen HI.

Also reset/free the per-link relocation map in TCCState.
2026-02-23 22:26:06 +08:00
Aleksi Hannula
4597a9621e
arm64-gen: consider VT_LONG|VT_DOUBLE for TOK_NEG 2026-02-07 12:08:17 +02:00
Aleksi Hannula
5ad52cc1ed
Cast signed pointer offset to ptrdiff_t before performing arithmetic
Affects 32-bit platforms.
2026-02-05 11:49:59 +02:00
Aleksi Hannula
c937095552
Fix numbered register substitution on x86_64 2026-02-05 11:49:59 +02:00
Aleksi Hannula
8c61b91de8
Remove libc dependency from lib-arm64
Moving the u128_t struct may invoke calls to memcpy/memmove when
compiled with tinycc, which would depend on libc.

For example, some configure scripts get confused if they fail to build
test programs involving long doubles. I'm not sure if this is the root
cause, though.
2026-02-05 11:49:59 +02:00
Aleksi Hannula
aeae4b4cee
arm64: Fix long double comparison operators 2026-02-05 11:49:59 +02:00
Aleksi Hannula
c39eaf10cf
arm64: Implement TOK_NEG for floats natively 2026-02-05 11:49:59 +02:00
Aleksi Hannula
1cb0a3d52a
Allow building an empty libtcc1 on AArch64 2026-02-05 11:49:59 +02:00
herman ten brugge
abb2f394dd i386: bound checking needs pic in shared library 2026-02-05 09:31:59 +01:00
Avi Halachmi (:avih)
4fccaf6124 Revert "build c2str.exe with the host compiler; default it to gcc if cross prefix given"
This reverts commit 41fa74fc84.

Reasons for the revert:

1. The commit message is lacking and the use case is not obvious.
   At the very least a concrete example of use case should be given
   (likely cross-building tcc on platform X for running on platform Y),
   followed by an issue description in such use case, and fix descr.
   (e.g. "On platform X, when running ./configure ... && make ..., the
   build fails because whatever. this commit does Y and fixes it").

2. assign_opt is used incorrectly: 1st arg must be --OPTNAME=VALUE
   but it's not. The only thing it does is unconditional host_cc=gcc
   if --cross-prefix=... is used - no need for "assign_opt" at all.

3. cross-building tcc currently has several triggers: build/target
   cpu differ, or build/target OS differ, or --cross-prefix=... is
   used, but that commit only covers the --cross-prefix=... case.
   It's possible that it's intentional to only cover one case, but
   if so then it's not explained why.

4. The var name host_cc is likely incorrect and probably meant to be
   "native_cc", judging by the assigned value "gcc".

5. "gcc" is used unconditionally in such case, without any way to use
   a different native compiler (assuming that's indeed the goal).
   A better approach is likely supporting --native-cc=... option which
   defaults to $cc (which already defaults to "gcc") _before_
   $cross_prefix is added in-front.
2026-01-18 09:04:54 +02:00
Urja Rannikko
41fa74fc84 build c2str.exe with the host compiler; default it to gcc if cross prefix given 2026-01-17 20:47:00 +02:00
noneofyourbusiness
b39cbc70c4
riscv64-asm.c: parse_operand: document some ABI details 2026-01-17 11:35:01 +01:00
grischka
5ec0e6f84b some reverts & fixes
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
workflow:
- revert 'pinact for security' for readability
  from 831c3fa184
tccpp.c:
- remove code that allows tcc to parse numbers incorrectly (*)
  from 829c848520
tccgen.c:
- Revert "Relaxed the 'incompatible pointer type' warning a bit" (*)
  from d9ec17d334.
tccrun.c:
- remove support for -nostdlib -run
  for simplicity, we require "main" with tcc -run always
tccpp.c:
- Revert "Free all preprocessor memmory in case of error."
  from c96f0cad61
  Remove TinyAlloc->limit instead.  Thus it can do also bigger
  allocs.  Big TokenStrings (like 200kb+ when compiling tcc)
  may come from inline functions or from large initializers.
Makefile/configure:
- use --config-pie for configuring tcc output only
- use -fPIC with clang-x86_64 to avoid 32-bit relocs
libtcc.c:
- fix "tcc file.c -run" i.e. -run as last argument
i386-gen.c:
- PIC refactor

(*) sorry, but code in tcc should have a minimum of generic relevance
2026-01-10 13:46:23 +01:00
herman ten brugge
518279dc3e Another update for macos
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
Sorry about last commit.
I had no access to a macos machine for a for weeks.
2026-01-09 08:25:28 +01:00
herman ten brugge
1401967ce2 Fix macos
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
I fixed macos problem with test case 60.
Also tccrun mmap and debug code did not work.
2026-01-06 16:01:28 +01:00
herman ten brugge
1fe3e3bff5 Add support to debug libtcc code
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
I tried several gdb/lldb options to debug libtcc generated code.
But gdb/lldb complained that they could not load symbols or
that module does not exist. There was also another problem. The
code itself was in memory (string) and gdb/lldb do not have
functions to acces it.

So I came up with a new api for debugging libtcc code.
First you enable debugging with: tcc_set_options(s, "-g")
Then compile the code with: tcc_compile_string_file(s, program, "<file>.c")
Then call tcc_relocate().
And finaly write the object file to disk: elf_output_obj(s, "<file>.o")
Now you can start the debugger and put an breakpoint after the
elf_output_obj() code. Then use gdb command add-symbol-file <file>.o
and from there on you can set breakpoints in the libtcc generated code.
You can also step/print variables/...
I could not find a simular function in lldb yet.

When debugging is done you remove the tcc_set_options(s, "-g").
All other code can remain because tcc_compile_string_file and
elf_output_obj do not output any file any more is debug is not set.

See also tests/libtcc_debug.c
2026-01-06 12:11:51 +01:00
herman ten brugge
8a8388c6ff Solve some bug reports
The savannah web site had some new bug report last december.
A lot of them are assemmbly bugs.
See testcase 60 for an overview.
2026-01-06 07:49:02 +01:00
herman ten brugge
9a7edb20d3 Add pic/pie support to i386
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
Some targets (netbsd) require that code is
compiled with -fPIE.

i386-gen.c:
Lot of changes to load/store code

i386-link.c:
Set PCRELATIVE_DLLPLT depending on configuration

tccelf.c:
Change some relocations and add get_pc_thunk.o

Makefile lib/Makefile lib/get_pc_thunk.S:
Add new file get_pc_thunk.o
2025-12-30 20:15:35 +01:00
Dylan Fei
5ce2c4b454 arm64-gen: fix 16-byte alignment for variadic arguments on stack
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
According to AAPCS64, when an argument requires 16-byte alignment
and is passed on the stack, the stack address must be rounded up
to the next 16-byte boundary.

TCC previously failed to perform this alignment check in gen_va_arg,
leading to data corruption when a 16-byte aligned argument followed
an 8-byte argument on the stack.

Note: This issue is most prominent on Mach-O/Apple Silicon where
variadic arguments are passed entirely on the stack. Testing shows
this fix resolves the failure on macOS while remaining compatible
with Linux/ARM64 (e.g., Raspberry Pi).

Modified gen_va_arg to perform a round-up (addr + 15) & ~15 when
align == 16.
2025-12-29 00:57:35 +08:00
Dylan Fei
b8513fe895 arm64-gen: fix address calculation for large symbol offsets
When accessing a global symbol with an addend > 0xffffff, the AArch64
backend incorrectly encoded an 'add xr, xt, #0' (Add Immediate)
instead of 'add xr, xr, xt' (Add Register).

This resulted in the base address of the symbol being overwritten
by the offset value rather than being summed with it.

Fixes the issue where (sym + 0x1000000) would resolve to 0x1000000
instead of the correct memory address.
2025-12-28 21:32:58 +08:00
Dylan Fei
11118be717 Fix pointer difference issue in aarch64/riscv64
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
When calculating the difference between two pointers (TOK_PDIV), the
AArch64 and RISC-V64 backends used unsigned division
instructions (udiv/divu).

This patch moves TOK_PDIV to use signed division instructions (sdiv/div)
for both backends, ensuring correct behavior as per the C standard.
2025-12-23 16:01:10 +08:00
herman ten brugge
5a370d8a6b Relocation updates
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
x86_64-link.c:
Check relocations R_X86_64_32/R_X86_64_32S. These relocations
can become to large if not configured with '--disable-static'
or '--config-pie' and code is run with -run -ltcc.
This only happens on x86_64.

tccdbg.c:
1) Add some .debug (dummy) sections when dwarf is used. These
   sections are otherwise not relocated correctly for R_DATA_32DW.
2) Fix stab problem when reloc is applied twice.
2025-12-23 06:46:22 +01:00
herman ten brugge
64cf0b816b undo x86_64-link.c commmit
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
The relocation check does not work with stabs enabled on some targets.
It works fine on fedora with and without stabs.

So remove check.
2025-12-21 18:49:21 +01:00
herman ten brugge
96119149fe Problems solved on for libtcc, pie, riscv64, arm64
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
I found some problems with a testcase from mailing list.

On x86_64 an overflow on reloc R_X86_64_32 occurred that was
not reported when using -run -ltcc.
The problem could be solved by compiling tcc with -fPIE, -pie
or --disable-static.

Makefile, configure, libtcc.c, x86_64-link.c:
- add --config-pie to configure help. Ignore -pie in libtcc.c
  and check reloc overflow in x86_64-link.c

arm64-gen.c:
- Fix reading from constant like '*(int *)0x7fffb7f1280c'

elf.h, riscv64-link.c:
- fix for -run -ltcc. Ignore reloc R_RISCV_SET_ULEB128 and
  R_RISCV_SUB_ULEB128 that are used in .debug_loclists section.
2025-12-21 07:05:55 +01:00
herman ten brugge
34eed88a70 Small updates
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
Allow 'make speedtest' in tests directory
Fix compiler warning tccpp.c
2025-12-17 20:22:08 +01:00
herman ten brugge
3c18df610d Fix clang macos 15 bug on arm64 in tests/tcctest.c 2025-12-17 19:54:22 +01:00
herman ten brugge
f3de8b5307 Use macos 15 in build.yml 2025-12-17 18:21:01 +01:00
herman ten brugge
8569427459 Move -run -nostdlib code to lib directory
tcc.h, arm-gen.c, arm64-gen.c, i386-gen.c, riscv64-gen.c, x86_64-gen.c:
- remove old code

tccrun.c:
- update to use lib/run_nostdlib.c

Makefile, lib/Makefile, lib/run_nostdlib.c:
- new code

tests/nostdlib_test.c:
- testcode
2025-12-15 14:45:11 +01:00
Stefan
829c848520 tccpp.c: Configurable integer literal overflow handling
Add the define TCC_CUT_ON_INTEGER_LITERAL_OVERFLOW to use the most
significant digits of an integer literal before its parsing led to an
overflow.

When compiling tcc with another compiler, which is not able to handle
64 bit arithmetic, it is beneficial to use the last value before an
integer literal overflows. Parsing 0x1000000000000000 then results in
0x10000000. The mescc from GNU Mes is able to compile a first tcc on a
32 bit system without 64 bit arithmetic. This change allows this first
tcc to compile a second tcc with complete 64 bit arithmetic.
2025-12-13 18:53:15 +01:00
Aleksi Hannula
cb41cbfe71
x86-64: Fix cvts*2si
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
Co-authored-by: Herman ten Brugge <hermantenbrugge@home.nl>
2025-12-03 17:21:00 +02:00
Reini Urban
831c3fa184 github CI: pinact run -u
for security
2025-12-02 16:31:13 +01:00
Aleksi Hannula
0fcd46f364
rv64: Generate VT_CMP output from float comparison 2025-12-02 07:30:31 +02:00
Aleksi Hannula
b4569233cb
Set TYPE_PARAM parsing mode in old-style param lists 2025-12-02 07:30:27 +02:00
herman ten brugge
f5f544f436 allow cross compiling for alloca on arm64 2025-12-01 18:09:04 +01:00
Aleksi Hannula
7479a5c21a
elf: Set ph sizes only if ph was allocated 2025-11-29 22:28:36 +02:00
Aleksi Hannula
78e5e690a2
rv64: Implement some pseudo-ops from Zicsr 2025-11-29 21:11:46 +02:00
herman ten brugge
6da45946ae Add bound check support for alloca on all targets
stddef.h, tccdefs.h, tccgen.c, tests/boundtest.c, tests/tcctest.c:
- remove ifdef arround alloca

lib/Makefile:
- move alloca-bt.o to COMMON_O

lib/alloca-bt.S:
- add alloca bound check code for arm, arm64, riscv64

lib/alloca.S:
- check for leading underscore

tcc.h, libtcc.c:
- include arm64-asm.c instead of arm-asm.c for arm64

tcctok.h, tccasm.c:
- add simple reloc support (only for R_AARCH64_CALL26)
2025-11-29 07:54:28 +01:00
Aleksi Hannula
fc424c9f7b
Reorder "pure" attribute
Placing the definition of "pure" prior to TOK_DEFINE would cause it to
be treated as a keyword by tccgen. This breaks building gcc, in which
"pure" is used as a struct field name.
2025-11-28 16:07:24 +02:00
Aleksi Hannula
5b96aeb7fc
Implement some SSE/2 instructions
This patch implements some instructions required by musl 1.1.24.
2025-11-28 15:23:09 +02:00
Aleksi Hannula
06e24e7eed
Implement some RV64F/D instructions
This patch implements some instructions required by musl 1.1.24.
2025-11-28 15:23:07 +02:00
Aleksi Hannula
3c631fdb6d
Implement alloca for RV64 2025-11-28 15:17:06 +02:00
Aleksi Hannula
e7be7b192d
Simplify RV64 function epilogue
Previous sp can be computed based from only frame pointer and short
offset. ra and s0 can be restored from stack with constant fp offset.
2025-11-28 15:17:06 +02:00
H-language
3327327e5d Add WM_MOUSEHWHEEL to winuser.h 2025-11-26 11:10:10 +13:00
herman ten brugge
7e4fc3a0d0 Fix alloca for arm
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-11-19 11:20:50 +01:00
kbkpbot
264229a0d4 Add arm64 alloca() support. 2025-11-19 17:17:05 +08:00
herman ten brugge
fa6a6bfbbd Move lib/va_list.c into include/tccdefs.h
This makes code with va_arg work with -nostdlib on x86_64.
2025-11-19 08:31:15 +01:00
herman ten brugge
3e8f1da9c5 Change asm into __asm__ in previous commit
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-11-17 19:17:53 +01:00
herman ten brugge
c52b96cf85 Allow -nostdlib -run
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
The -run option did not support -nostdlib correctly.
The argc/argc/envp are now passed on stack according to sysv.

This implementation does not work for TCC_TARGET_PE.
Also arm64 does not work when running tcc compiled with itself.
This is because arm64 assembly is not implemented yet.

The following test code is used to check the code:

  #include <unistd.h>
  #include <sys/syscall.h>
  void _start() {
    syscall(SYS_write, 1, "hello world\n", 12);
    syscall(SYS_exit, 0);
  }

Run this with:
./tcc -nostdlib -lc -run a.c
make tcc_c
./tcc_c -nostdlib -lc -run a.c
2025-11-17 14:00:15 +01:00
DFP
d9ec17d334 Relaxed the 'incompatible pointer type' warning a bit
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
Do not emit that warning when the source struct (recursively) contains destination struct as the first member. For example, in this case the warning would have been emitted before, and is not anymore:

struct base {
	int a;
};

struct derived {
	struct base base;
	int b;
};

struct derived derived;
struct base *base = &derived;

I personally use that pattern in my code (in a bit more elaborate form) and so this change removes the warnings for those use cases, while still retaining it for everything else. Feel free to CC me on the mailing list if you have questions, suggestions or complaints.
2025-11-14 08:55:55 +01:00
herman ten brugge
ab2ce3b13a Ignore some more attributes
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
Detected when using -Wunsupported
2025-11-04 15:03:19 +01:00
Detlef Riekenberg
cdebce3079 tccpp: Add the define __STDC_HOSTED__ [C99]
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
Usually defined to 1, but when using "-nostdlib", the value is 0
(required for C99)

--
Regards ... Detlef
2025-11-01 18:11:49 +01:00
Avi Halachmi (:avih)
f4e01bfcab tcc -run: support custom stdin with -rstdin FILE
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
When tcc -run is used with input file from stdin, then run_main's
stdin (which is tcc's stdin) is already EOF after we've read it.
If the program operates exclusively on stdin, then it cannot be used.

This commit adds an option -rstdin FILE which sets run_main's stdin.

Can also be used in such case to set run_main's stdin to the tty,
using -rstdin /dev/tty (posix) or -rstdin con (windows).
2025-10-27 14:50:56 +02:00
Avi Halachmi (:avih)
234e2dd2bf tcc options: document behavior and clashes (no-op)
The tcc options behavior is non trivial, and it's also susceptible
to ambiguities - which do exist (but currently are not painful).

- Add a script 'optclash' which detects clashes/ambiguities.
- Document the parsing behaviour and current clashes/resolutions
  as comments in libtcc.c .
2025-10-27 14:50:54 +02:00
Aleksi Hannula
01d1b7bc76
Add support for f{l,s}d in riscv64-gen
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-10-17 15:40:08 +03:00
herman ten brugge
19589288cb Some fixes and cleanups
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
tcc.h, tccgen.c:
  Add and use IS_BT_ARRAY
tccpp.c:
  free memory when size is 0 in realloc code
tccdbg.c:
  move common code to seperate function remove_type_info
2025-10-16 07:35:27 +02:00
herman ten brugge
edcd228214 Init global_expr variable
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
This is needed when errors occur when compiling with libtcc.
A next compile with libtcc results in undefined symbol.
2025-10-15 10:02:09 +02:00
herman ten brugge
96229004c4 Fix debugging after commit tccgen: more of scope hacks
The commit added some extra defines that where not
handled in debugging code.
2025-10-15 09:01:54 +02:00
herman ten brugge
c96f0cad61 Free all preprocessor memmory in case of error.
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-10-13 15:57:31 +02:00
grischka
34b45a69ff Reverts & cleanups
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
- include/stddef.h, tcctest.c
  Revert "tests/tcctest.c: include stdint.h"
  This reverts commit 8f23997ca7
  We don't want tcctest.c to rely on system include files

- libtcc.c:
  Revert "libtcc.c: Remove unused defines free and realloc"
  To be unused is the point why they do exist
  This reverts commit 2f88764100.

- tcc.c:
  fix formatting of commit e73529865d

- tccpp.c:
  parse_include(): print skipped include files too (with tcc -vv[v] file)
  next_nomacro(): faster L"str" parsing

- tccgen.c: fix c2y if declaration:
  * accept like GCC: if (int a = 0, b, c = x; c)
  * accept as "TCC extension": if (int a = 0, b, c = x)
  * "speak tcc" with symbol/function names

- README:
  cleanup
2025-10-09 13:08:33 +02:00
herman ten brugge
ce8b3432bf Allow gcc 16 for build
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-10-07 14:32:13 +02:00
Stefan
bcfb872fd0 Makefile: Add space behind 'install -m'
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
There are install shell scripts around, often derived from X11 like
contained in glibc or Gash sources, which require to separate -m from
its value. Therefore add a space behind 'install -m' in the Makefile.
2025-10-03 17:58:45 +02:00
Stefan
ba0899d909 tccasm.c: Make .init and .fini sections executable
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
GAS selects default attributes for a section based on its name and makes
the sections .text, .init, .fini executable. The crti.s and crtn.s files
of musl rely on these defaults and don't set the "x" flag for the .init
and .fini sections. Unfortunately TCC does not care for .init and .fini
section defaults in assembler or C code. Fix this for assembler code.
2025-09-21 14:06:59 +02:00
Stefan
2f88764100 libtcc.c: Remove unused defines free and realloc
These defines are not used in the code below their definition. They are
defined in tcc.h as well.
2025-09-21 13:30:15 +02:00
Stefan
95d184cba1 i386-asm.c: Optional % for variables in specific registers
Handle 'register long r10 __asm__("%r10")' without %, too. Using GCC
the % is optional. The musl source code does not use the % prefix.
The GCC source code uses both variants.
2025-09-21 13:18:37 +02:00
Stefan
5aebf106e8 i386-asm.c: Use NB_ASM_REGS instead of 8
For x86_64 there are more than just 8 registers.
2025-09-21 12:21:27 +02:00
Stefan
9dc59f9c23 i386-asm.c: Do bit-check for OP_SEG in asm_opcode
Fix a bug with "call *%%gs:16", which sets the two flags OP_INDIR and
OP_SEG in pop->type.
2025-09-21 12:18:11 +02:00
grischka
de8c19e1da tccgen: globalize function return type too
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
Commit 38ab5f65b3 was missing
to move the function return type to the global stack too.

Also, check redefinition in sym_push(), as before.
2025-09-18 19:32:19 +02:00
noneofyourbusiness
47106ce103
tccgen.c: silence logical op warning
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
behavior is unchanged
2025-09-18 11:42:58 +02:00
noneofyourbusiness
8f23997ca7
tests/tcctest.c: include stdint.h
despite being defined in tcc's own stddef.h, intended to be included by
libtcc.h, libtcc.h actually included the libc's standard include

tested on musl
2025-09-18 11:17:55 +02:00
noneofyourbusiness
e73529865d
tcc.c: add information about reporting bugs to the mailing list 2025-09-18 09:58:21 +02:00
grischka
38ab5f65b3 tccgen: more of scope hacks
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
* case 1: local scope of 'ff'
  int main() {
    int ff = 123;
    {
      int ff(int):
      ff(456)
    }}

* case 2: linkage of a static extern symbol
  (older gcc did allow that)
  static int ff(int);
  int main() {
    int ff(int):
    ff(456)
  }

Also:
- cleanup enum, let sym_push() handle redefinition
- just mark incomplete array base types, unshare only
  when needed (in decl_initializer_alloc())
- fix sizeof empty array (= 0) : int ii[] = {};
- rename 'Sym' members used by __attribute__((cleanup(f)))
2025-09-08 17:23:18 +02:00
grischka
ce4de961af tccpe: add COFF symbol table for GDB
wanted by gdb to have global variables info on windows

Also:
tcc.h:
- move dwarf inline fns
- use dwarf as default for 64-bit platforms. GDB can't handle
  locals info from stabs on 64-bit correctly (also not from gcc).
tccpe.c:
- use 's1' instead of 'pe->s1'
tccdbg.c:
- fix locals info problem on Windows where (unsigned long) s->value
  is uint32_t and would not cast to long long correctly.
- tweak dwarf to have line info at begin of functions, otherwise
  "gdb b main, r, n" would say "no line number info, single step..."
  (see also objdump --dwarf=decodedline ...)
2025-09-08 17:22:21 +02:00
herman ten brugge
03072a301c Use configure to set note release bsd
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
Using uname in tccelf.c was not working when cross compiling.
So move it to configure script.
2025-09-04 06:47:40 +02:00
herman ten brugge
8c3396a76f Fix cross compiling on windows
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
2025-09-03 07:43:01 +02:00
herman ten brugge
b45cea5f4b Update bsd notes
freebsd 13 must not have note section.
freebsd 14 must have note section.

also added version info.
2025-09-03 07:09:42 +02:00
herman ten brugge
b427545419 Update for freebsd versions >= 14.0
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-08-31 12:24:03 +02:00
herman ten brugge
e6ea0d0424 tccgen: fix several problems
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
Fix 'void func2(char *(*md)(char *md))' declaration.
Fix global array and local extern array problems.
Fix scope problem with old function declaration.
Fix 'typedef int t[]' declaration. Empty size should remain.
2025-08-30 07:13:49 +02:00
herman ten brugge
8c59fd3cb6 Check enum range for typed enums
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-08-24 11:22:38 +02:00
herman ten brugge
6ca6328e29 Fix long double to long long for x86_64
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
2025-08-23 14:48:34 +02:00
grischka
acb2a909dd tccgen.c: fix two scope problems
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
... see tests

Also:
- tccgen.c: cleanup _Generic a little
- libtcc.c: cleanup mem-debug a little
- arm-link.c: read/write only once
- tcc.h: another fix for clang offsetof
- tccdbg.c:
  * stabs: handle forward struct/enum decls
  * stabs: fix anonymous struct members (must not have a .L123 name)
  * avoid strncpy()
2025-08-22 19:14:44 +02:00
herman ten brugge
4e6c4db340 Small debug cleanup
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
A little bit better string hashing
Move free code to seperate function
2025-08-22 16:45:06 +02:00
herman ten brugge
e5e3dc687b Make debug info smaller
Currently debug size is big because some types are output multiple times.
Function scope was not treated correctly.
Rename anon(ymous) into forw(ard).
Compact string table by reusing names.
2025-08-22 10:27:59 +02:00
Matthias Gatto
f52b480f89 c2y if declaration (std n3356)
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
standart is here: https://www.open-std.org/JTC1/SC22/WG14/www/docs/n3356.htm

This feature should not add bug to existing features,
as it is called only if there is a declaration in a switch or an if.
2025-08-22 00:01:58 +02:00
herman ten brugge
80e7040d0c tcc loops with some input arguments
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
This is one example:
tcc -c a b -o c

Detected with some configure scripts.
2025-08-18 22:28:05 +02:00
grischka
2662b7b43c tccgen: local scope for types of function parameters
int foo(struct xxx {int x[3];} *p) { ...

We want 'xxx' be visible only inside the function. To get that,
the patch removes the 'sym_push(param)' in xxx-gen.c, and instead
(in tccgen.c:gen_function()) pushes all symbols that were newly
defined during parsing of the parameter list in post_type().

Also,
- decl_initializer_alloc():
  patch existing globals earlier, which updates flex arrays too
- let patch_type() do the 'redefinition' check and FUNC_OLD update
2025-08-18 21:06:03 +02:00
grischka
deb7a3fc73 tcc.c:main() free all & etc...
tcc.c:
- be nice to leak checkers
tcctools.c:
- remove unused TCCState params
tccrun.c:
- call bound_exit() after signals to let it free mem
tccelf.c:
- use section_add() instead of section_ptr_add() when
  more appropriate
tccpp.c:
- use size_t to align tal_header naturally
- 'POINTER_SIZE' and 'PTR_SIZE' in the same source is confusing
- "char file_name[TAL_DEBUG_FILE_LEN + 1];" looks silly.
- next_nomacro(): skip UTF8 BOM at BOF
tccgen.c:
- get rid of STMT_EXPR clause on top of block
- warn with useless type like 'int;'
- move skip()'s in block() for better error line-info
- BIT_SIZE bits are meaningful only with VT_BITFIELD
  (not with enums for example)
workflow/test-win32:
- build with MSVC using build-tcc.bat also
alloca.S:
- fix 'off by one' problem on win32 (must touch current page
  too because the 'push %edx' at the end could touch the next page)
- must not align greater than 4 when used for struct args
  (i386-gen.c:gfunc_call())
libtcc.c:
- accept -g1dwarf (dwarf output, only line info)
2025-08-18 20:43:52 +02:00
herman ten brugge
8845b6cd45 Make signed/unsigned bitfields the same as gcc/clang 2025-08-18 16:22:00 +02:00
herman ten brugge
199e135142 arm double to (unsigned) long long conversion
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
Bug found with openssl test suite.
2025-08-17 08:49:29 +02:00
herman ten brugge
f8eb5f4ab8 Add -znodelete linker option
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
This option is needed for openssl to create a correct library.
2025-08-16 18:29:19 +02:00
herman ten brugge
19fdef46f9 Allow mixing old/new function prototypes
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
This fixes another external testsuite failure
2025-08-15 09:59:11 +02:00
Marek Knápek
571868c4f7 Fix for MSVC's usage of __declspec(align(#)).
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
2025-08-15 04:41:24 +02:00
herman ten brugge
03184fe33b riscv target did not handle FUNC_OLD correctly.
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-08-11 06:49:22 +02:00
herman ten brugge
37e1c88d78 Convert float to double for old function code.
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
2025-08-10 22:02:44 +02:00
herman ten brugge
087cf2e579 x86_64 bound checking failure
The code:
void mul(double *p)
{
    *p *= 2.0;
}

failed on x86_64 because register was not loaded after
bound checking call.
Also printed size when pointer indir failes.
2025-08-10 21:55:48 +02:00
herman ten brugge
fa9795406d Do not read past array end in struct return
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-08-07 11:32:09 +02:00
herman ten brugge
9dffcd29d3 Fix tests/boundtest.c
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
The test leaks memory on arm/arm64/riscv because alloca is
replaced by malloc and the memory is not freed for test16 and test17.
2025-08-05 22:14:13 +02:00
herman ten brugge
311218ee5f Allow testsuite to be build with CC -fsanitize
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
Makefile: Add sani-test* targets + help
tcc.h: redefine offsetof for clang -fsanitize
tccelf.c: section_ptr_add: allow clang -fsanitize
          tcc_add_btstub/tcc_load_object_file: revert previous change.
tccpp.c: Fix -fsanitize problem by casting to unsigned.
tests/Makefile: tcc -v leaks memory (a lot of returns in main() leak memory)
tests/tests2/Makefile: testcase 112 aborts and leaks memory. Disable leak test.
2025-08-05 16:47:11 +02:00
herman ten brugge
5364bc7c82 Fix i386 alloca code.
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
I commited the wrong version in previous commit.
2025-08-03 18:41:32 +02:00
herman ten brugge
6694391b74 Update gcctestsuite
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
I updated the tests/gcctestsuite.sh a bit.
before:
  3329 test(s) ok.
  210 test(s) skipped.
  168 test(s) failed.
  28 test(s) exe failed.
after:
  3331 test(s) ok.
  299 test(s) skipped.
  79 test(s) failed.
  26 test(s) exe failed.

I found some small problems:
include/tccdefs.h: Add alloca definition for i386 and x86_64
lib/alloca.S/lib/alloca-bt.S: align i386 alloca to 16 bytes.
			      i386_gen.c vla code and gcc do the same.
x86_64-gen.c: fix typo in comment
2025-08-03 10:35:58 +02:00
herman ten brugge
80bef6162a Unshare typedef definitions if it used more then once. 2025-08-03 10:29:16 +02:00
herman ten brugge
8a0ccbbd94 Another update for clang -fsanitize
arm-link.c:    remove some casts
tccelf.c:      code style and remove code
tccpp.c:       use correct pointer size so cross compiling works
riscv64-gen.c: make code more readable
2025-08-03 10:22:26 +02:00
herman ten brugge
666e88ee2a Update for clang -fsanitize
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
I tried to fix all remaining warnings/errors reported by -fsanitize.

The riscv64-gen.c is a bit large because it contained a lot of warnings.
I forgot some arm-link.c changes in last commit.
The other changes are all small fixes to avoid warnings/errors.
2025-07-29 08:26:57 +02:00
herman ten brugge
8025a829cc Check with clang -fsanitize
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
Tested code with:
clang -fsanitize=address,undefined,nullability -pie -fPIE -Iinclude -I. -g tcc.c -o tcc.tcc -lm -ldl -lpthread
./tcc.tcc -Iinclude -I. -b -g tcc.c -o tcc.tcc1 -lm -ldl -lpthread

Also checked on i386/x86_64 with -fsanitize=memory (others not supported).

arm-link.c: use read32le/write32le/add32le to avoid unaligned access
tcc.h i386-asm.c: fix signed left shift
lib/bcheck.c: Add _Atomic
libtcc.c: Correct MEM_DEBUG_CHECK3 to avoid unaligned access
riscv64-link.c: Fix R_RISCV_SET16
tccpp.c: Align tal_header_t to avoid unaligned access
tccgen.c x86_64-gen.c: avoid use of uninitialized value

There are still warnings reported:
tccgen.c:4031:13: runtime error: member access within null pointer of type 'TCCState' (aka 'struct TCCState')
tccelf.c:321:22: runtime error: applying zero offset to null pointer
tccelf.c:1132:23: runtime error: applying non-zero offset 169184 to null pointer

A lot of left shift of negative value warnings.

I ignored these for the moment.

Also the -run option does no work well with -fsanitize. It gets confused
because it does not detect that the generated code in memory is used
without -fsanitize option.

There are a lot more -fsanitize options. I did not find serious problems
with them.
2025-07-27 11:22:16 +02:00
DAVID
a2902d37a1 testing
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-07-21 00:48:51 -03:00
Haelwenn (lanodan) Monnier
2ffb5869e0 lib/atomic.S: add GNU libatomic copyright notice
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-07-19 00:30:12 +02:00
herman ten brugge
2eca4df6e9 Correct riscv load_large_constant
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
2025-07-18 08:15:58 +02:00
herman ten brugge
7c23c48a93 Riscv struct saving
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
While adding some testcases for attribute cleanup I found a
bug in the riscv code. It modifies the sv->c.i in load_symofs.
If a structure contains more then one element only the
first is stored correctly. This only happens on a large
stack frame.
Fixed by saving/restoring sv->c.i.
2025-07-17 06:50:15 +02:00
grischka
9670d10294 fix github CI & stuff
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
workflows/build.yml:
- win32/64: install mingw32/64 gcc on msys (because the default
  gcc installed elsewhere seems to use ucrt, producing incompatible
  fp printf formats.)
tccgen.c:
- cleanup funcs: save any lvalues from return expressions.  Also use
  get_temp_local_var() which however was causing a problem on i386
  because its gfunc_call() removes the arguments from vstack and by
  that defeats the 'in-use'  tracking of get_temp_local_var().  Fixed by:
i386/arm/arm64/x86_64-gen.c:
- in gfunc_call(): save_regs before anything else, fixes
  problems seen in arm64/i386
tccpp.c:
- allow arm asm specific use of '#' in macros
libtcc.c:
- organize -M options, and:
tccpe.c:
- move the subsystem option parsing from libtcc.c
tccelf.c:
- improved error handling in tcc_load_ldscript()
lib/atomic.S:
- TCC_TARGET_... not defined when building the lib
- endbrNN security feature not supported by TCC
tests/tests2/136_atomic_gcc_style.c:
- never use standard assert() in tests
2025-07-16 21:32:21 +02:00
herman ten brugge
28d7fb85b2 Change windows_2019(deprecated) to windows_2022 in buid.xml
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-07-14 16:39:33 +02:00
herman ten brugge
717a510a19 Enable atomic test for all targets 2025-07-14 15:37:13 +02:00
herman ten brugge
7657d871c1 Add endbr32 for i386
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
2025-07-14 08:27:14 +02:00
herman ten brugge
854d6c5ab4 Update arm and windows atomic functions
I edited the arm thumb code so it works on armv6k.
I used the minga64w libatomic.a for windows.
2025-07-14 08:17:42 +02:00
kbkpbot
0c12363fd3 arm64: Save func results before struct args
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
In gfunc_call(), structure members are loaded into registers during
argument handling.
This operation may overwrite previous function call results stored in
registers (e.g., s0). To prevent this, we must save function call
results to the stack before processing structure arguments.
2025-07-11 22:13:30 +08:00
herman ten brugge
32b597746c Update bcheck for recent atomic change
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
The functions fetch_and_add_arm, fetch_and_add_arm64 and
fetch_and_add_riscv64 where removed with atomic change.

Replace the code in bcheck.c with call to atomic_fetch_add.
2025-06-24 21:38:31 +02:00
kbkpbot
7f13f24e12 Use asm implements some atomic functions
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
Use asm implements for i386/x86_64/arm/aarch64/riscv:

 __atomic_load_[1,2,4,8]
 __atomic_store_[1,2,4,8]
 __atomic_compare_exchange_[1,2,4,8]
 __atomic_test_and_set_[1,2,4,8]
 atomic_thread_fence
 atomic_signal_fence
 atomic_flag_test_and_set
 atomic_flag_test_and_set_explicit
 atomic_flag_clear
 atomic_flag_clear_explicit

`atomic.S` is extracted from `gcc` v15.1.0 `libatomic.a`.
And generated by https://github.com/kbkpbot/gen_atomic.git
2025-06-24 22:40:07 +08:00
Urs Janssen
3f06cb0f2e always search library paths 2025-06-24 14:23:47 +02:00
Avi Halachmi (:avih)
2d4e4a69c4 win32: winbase.h: fix broken LOAD_LIBRARY_AS_IMAGE_RESOURCE
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
Typo fix: s/LINRARY/LIBRARY/
2025-06-23 10:30:24 +03:00
Detlef Riekenberg
5fad6dc4a3 libtcc: Fix a double free, when option -o is used twice
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
tcc_set_str() already calls tcc_free() to free the memory of the stringpointer in s->outfile.
With the additional tcc_free(), the memory would be freed twice.

--
Regards ... Detlef
2025-06-19 03:27:59 +02:00
Detlef Riekenberg
f2b9fcf85d libtcc: Avoid a regression for some usecases
Thanks tylo for hints on the mailing list

--
Regards ... Detlef
2025-06-19 03:12:41 +02:00
herman ten brugge
59aecdb539 Another hex float fix
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
Hex floating point number did fail when a lot of digits are present.
See testcase 70.
2025-05-28 21:33:30 +02:00
herman ten brugge
c6792dac03 Add LIBS when testing tccb on bsd
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
ldexpl is in -lm library on bsd
2025-05-27 20:50:33 +02:00
herman ten brugge
cb39bc4cac Calculate hex floating point with 128 bits instead of 64 bits.
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
2025-05-27 07:36:33 +02:00
grischka
83de532563 revert "Save registers around attribute cleanup" (almost)
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
In fact, we don't need to save registers.  We need to
save the symbol if it is a SValue on vstack (the return
value in this case)

Replaces b6a16e3be4
2025-05-25 00:20:23 +02:00
herman ten brugge
b6a16e3be4 Save registers around attribute cleanup
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
This makes attribute cleanup code work the same as gcc and also
makes bound checking a very little bit faster.

tcc.h:
  Add save_return_reg(CType *) and restore_return_reg(CType *)
  Change gfunc_epilog() to gfunc_epilog(Sym *)

arm-gen.c:
arm64-gen.c:
c67-gen.c:
i386-gen.c:
il-gen.c:
riscv64-gen.c:
x86_64-gen.c:
  Move save and restore register around bound_local_delete call
  to save_return_reg and restore_return_reg.
  Pass func_type from gfunc_epilog to gen_bounds_epilog.

tccgen.c:
  Call save_return_reg/restore_return_reg in try_call_scope_cleanup
  when RETURN is found.

tccrun.c:
  Fix warning when bound checking not used.

tests/tests2/101_cleanup.c
tests/tests2/101_cleanup.expect
  Extra checks attribute cleanup save/restore registers.

tests/tests2/Makefile:
  Fix when bound checking not used.
2025-05-22 16:58:12 +02:00
Detlef Riekenberg
6ca228339c arm-asm: Accept additional register names
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-05-07 22:29:46 +02:00
Detlef Riekenberg
30c2373c8a Accept -MMD,depfile for the Linux Kernel 2025-05-07 22:25:29 +02:00
kbkpbot
36ff4f52b5 Add GCC-style atomic builtins: __atomic_*_n
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
This commit adds GCC-compatible atomic builtins to stdatomic.h for
better compatibility with code relying on GCC's atomic primitives.

1. ​**​New Macros​**​:
   - `__atomic_compare_exchange_n`.
   - `__atomic_load_n`.
   - `__atomic_store_n`.

2. ​**​Motivation​**​:
   - Improves compatibility with codebases using GCC's atomic builtins
     directly.
   - Simplifies atomic operations by allowing direct value passing
     (instead of pointers), enhancing code readability.
   - Aligns TCC's atomic support closer to GCC/Clang for cross-compiler
     projects.

3. ​**​Testing​**​:
   - Verified with basic test cases (integer CAS, load/store) on x86.
   - Confirmed no regressions in existing atomic operations.

- This change does not affect existing C11 `atomic_*` APIs.
- Struct types are intentionally unsupported in `_n` variants due to
  complexity.
2025-04-19 08:05:27 +08:00
grischka
f10ab130ec linker options & tcc_load_ldscript() reworked
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
cleanup libtcc.c:tcc_set_linker()
cleanup tccelf.c:tcc_load_ldscript()

Also
- tccrun.c, tccelf.c:relocate_syms():
  with tcc -run -nostdlib, do resolve but only from explicitly
  on the command-line given libraries.
- tccgen.c: optimize UMOD x % c -> x & (c-1) for c = 2^n
- tcc-doc.texi: cleanup
- tcc.h, tccpp.c, libtcc.c: add 'size' arg to pstrncpy()

Also reorder functions in libtcc.c a bit.
9 files changed, 556 insertions(+), 617 deletions(-)
2025-03-28 21:23:19 +01:00
grischka
b3381269d7 pp-expression numbers always long long
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
Aka 'intmax_t', as recommended by newer standards.
For example
    if (-0x80000000 < 0) is false,
but
    #if (-0x80000000 < 0) is true
because in C, 0x80000000 is an unsigned int, Whereas in
a preprocessor expression, it is a signed long long, even
without LL suffix.
2025-03-26 20:36:33 +01:00
grischka
f57cc34a0c Revert "Fix tcc -run on Windows" (almost)
Oviously what the patch wants is... on Windows, with
"tcc c:/dir/xyz.dll -run file"... pass the absolute
path of the dll to LoadLibrary() which can make sense
in situations.

Other changes in the patch to other platfurms seem to
have no effect. This reverts 52a9a541b0
except 2 lines in tccpe.c.

Also revert _Float16 patch a06c608625
As long as tcc does not really handle _Float16, we can just define
it in tccdefs.h.

Also move uint128_t to tccdefs.h for same reason.

Update github action (might fix random arm64 crashes)
2025-03-26 20:36:20 +01:00
Detlef Riekenberg
5527ca6dcb libtcc: Remove unrelated debug code
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-03-20 00:34:39 +01:00
waterlens
52a9a541b0 Fix tcc -run on Windows
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
2025-03-19 12:03:52 +08:00
waterlens
a06c608625 Add fake _Float16 type to enable the latest math.h on macOS
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
2025-03-19 00:23:20 +08:00
grischka
8c4e67380e arm bits
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
arm-asm.c: add forward branches & some ops
lib/armeabi.c: faster i/udivmod (asm)
arm-gen.c: use movw/movt to load constants for CPUVER >= 70
configure: use dwarf-4 debug sections on android, detect idiv
lib/Makefile: always add -I$(TOP) for access to config.h
tcdbg.c: add a "code mapping symbol" to help out llvm-objdump
tccelf.c: don't load SHT_ARM_EXIDX, modify ARM.attributes
tccpp.c: accept '@' for arm asm comments
2025-03-11 22:56:22 +01:00
grischka
006174449e cleanups & stuff
libtcc.c:
- free 'elfint' string
- acceot  -O and -Os
- accept -gstabs (to override dwarf when default)
- better -Wp,...

tccpp.c:
- #line cleanup
  also warn with "extra tokens after directive"

tccgen.c & xxx_gen.c:
- force CPU flags to register earlier

tccelf.c:
- tcc_load_object: align size only for code sections
  data/bss objects are always put with their specfic type align
      (in decl_initializer_alloc())
  x86/64 doesn't need aligned code
  from c6afdff7ab

tccpe.c:
- enable dllimport for "_imp__<sym>" also from assembler

x86_64-gen.c & lib/libtcc1.c:
- simpler fneg without libtcc1 reference

tests2/134_double_to_signed.c:
- a tcc compiled by msvc won't pass this test
2025-03-11 22:56:01 +01:00
Reini Urban
f075851f9d tcc -hh: missing \n
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
2025-03-11 13:16:39 +01:00
remph
6ec4a10652 Process linker directives beginning with a colon
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
eg. -l :crti.o, with the same meaning as for other linkers (search library
paths for an exact match)

Also clean up some copy/pasting
2025-02-16 13:44:37 +00:00
remph
1747b45649 Fix -Wl,-nostdlib behaviour for compatibility with other compilers
TCC treats -nostdlib and -Wl,-nostdlib as equivalent, but on other compilers
which call a discrete linker, -nostdlib behaves as on tcc (not adding
startfiles/libc/endfiles) by modifying the ld command line, but -Wl,-nostdlib
adds -nostdlib to the ld cmdline, which stops the linker searching the default
directories for libraries.
2025-02-16 13:43:37 +00:00
remph
ec60d28e0f Add -Wl,-I and -Wl,-dynamic-linker options
Compatible with ld.bfd, gold, lld and mold. Also, document existing
behaviour of LD_SO environment variable
2025-02-16 13:35:20 +00:00
remph
f8bd136d19 Update tcc-doc.texi: bring in line with `tcc -hh' output
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
2025-02-13 02:50:05 +00:00
herman ten brugge
f6385c0530 Use TOK_PPNUM/TOK_PPSTR instead of TOK_CINT/TOK_STR
I noticed that '#line 0x20' worked.
So use the preprocessor macros.
2025-01-06 19:46:04 +01:00
herman ten brugge
999ec460a6 Allow macro in #line directive
Using:
  #define LINE1 10
  #line LINE1
  #define LINE2 20
  #define FILE "file"
  #line LINE2 FILE
Should now work.

Add new testcase tests/pp/23.S
2025-01-05 20:10:06 +01:00
herman ten brugge
68000c01ae Print correct values for testcase 134 on all targets
Testcase 134 only worked on x86_64 and i386 not on other targets.
2024-12-30 07:31:16 +01:00
kbkpbot
eef2db71a9 revert commit b8b6a5fd7b
As it will cause printf("%llu\n", (unsigned long long)1e19); output
9223372036854775808
instead of
10000000000000000000
2024-12-30 12:19:01 +08:00
herman ten brugge
c6afdff7ab Aligb section at end in tcc_load_object_file
Noticed this when the crt1.o file on an updated riscv had a
text section where the size is not multiple of align.
This file is loaded first and when the c code is then compiled
the code is not aligned any more.
This results in:
alignment of code section not multiple of 4
in riscv64-gen.c
2024-12-27 09:19:03 +01:00
kbkpbot
90ae383f62 x86_64/i386: Add missing fetch CPU flag
In x86_64-gen.c/i386-gen.c, gfunc_call will generate structure store
for bt == VT_STRUCT. Before generating any code, it is needed fetch
cpu flag.
As #ifdef TCC_TARGET_PE, gfunc_call() forgot to do this.
2024-12-26 19:17:49 +08:00
kbkpbot
af1cfd9e82 fix x86_64/i386 gfunc_call, when arg is VT_STRUCT, need fetch cpu flag before generating any code 2024-12-26 12:30:07 +08:00
Scott Graham
34b7b2cef5 Add lib/builtin.c to win32/build-tcc.bat
It looks like this is in the Makefile build, and it appears to be
necessary to make __builtin_ctzll available.
2024-12-15 12:49:16 -08:00
grischka
8620a312b2 tcc -run file.c : pass original exit code from file.c again
when there are no other errors then exit tcc with the exit cude
from tcc_run() (messed up in dd2e5f8b06)

Also in tccrun.c, use a more exotic random value to replace zero
with 'exit(0)' in user code (because lonhjmp(jb, c) needs c != 0)
2024-12-13 10:55:25 +01:00
Keith Thompson
b776bfaa53 Define LDBL_MAX_10_EXP for aarch64, riscv
There was a duplicate definition of LDBL_MAX_EXP, which this commit
removes.

There was a missing definition for LDBL_MAX_10_EXP, which this
commit adds.

I've confirmed the value of LDBL_MAX_10_EXP using gcc on an AARM64
Debian system (gcc 8.3.0).  I've only indirectly confirmed the value
on RISCV (using "#if ... #error" on godbolt.org).  I'm reasonably
sure this update is correct, but someone should confirm it before
merging to "mob".
2024-12-12 18:25:20 -08:00
herman ten brugge
ea75d5cf39 Add symver support for FreeBSD >= 14 2024-12-12 20:59:50 +01:00
Scott Graham
0ce0533854 add AddVectoredContinueHandler and AddVectoredExceptionHandler to kernel32.def 2024-12-12 11:56:19 -08:00
herman ten brugge
68c8c352fd Avoid Invalid relocation and section conflict on bsd.
With recent changes I got:
/usr/lib/crtbegin.o: error: Invalid relocation entry [ 2] '.rela.text' @ 0000007a
And:
libtcc.o: error: section type conflict: .eh_frame 01 <> 70000001
2024-12-12 20:46:00 +01:00
Avi Halachmi (:avih)
d440ed819c lib/Makefile: fix out-of-tree build of lib/bt-exe.c
Commit a522213 ("tccpe.c: never assume static...") removed the global
-I$(TOP) for cleaner lib build, and ensured that it is added for
bcheck.c as it now includes config.h, but forgot that bt-exe.c also
needs config.h, as it includes ../tccrun.c which includes it.

Also, the explicit tccrun.c prerequisite for bt-exe.c is not required,
as all *.o lib files depend on $(TCC), which depends on libtcc, which
depends on tccrun.c .

Also, at win32/built-tcc.bat, while bcheck.c needs -I.. for config.h,
bt-exe.c doesn't, as ../tccrun.c does find it where it expects it.
2024-12-07 00:53:16 +02:00
grischka
a522213cc8 tccpe.c: never assume static system libtaries
just clear s1->static_link before loading msvcrt etc.

Also:
- configure: get cc_version/name when making a cross compiler too
- configure: fix android triplets
- Makefile: remove CONFIG_TCC_CROSS, check TCC_TARGET_xxx instead
- libtcc.c: parse some linker option arguments more correctly
- tccelf.c: fix a versym problem with clang on android
- lib/Makefile, build-tcc.bat: bcheck.c now includes config.h
2024-12-06 16:21:30 +01:00
Avi Halachmi (:avih)
315828720d configure: --config-mingw32: clarify values, simplify code
Elsewhere at configure the value of $mingw32 is expected to be
exactly either yes or no (not empty, not caps, etc), and while it
complies internally, it also accepts arbitrary override value.

Clarify acceptable values, and simplify the parsing.
2024-12-04 20:04:08 +02:00
Avi Halachmi (:avih)
126b1ffd10 configure: win32: error only once about 'ln failed'
Don't try ln again if it failed, it won't have better luck next time.
2024-12-04 20:04:08 +02:00
Avi Halachmi (:avih)
c45559e124 configure: handle spaces correctly in $source_path
Add very few missing quotes where IFS/globs were applied to arbitrary
user input (commands, arguments, but not assignments or case $var in.
In fn_makelink $dn/$2/$f don't have IFS/globs).

While configure now handles it correctly, there are 2 issues:
- eval opt=\"$opt\"  coalesces IFS chars (--prefix="$HOME/x   y").
- Even with the eval removed, (gnu) make still fails to find it.

I made few quick experiments with quoting these values in config.mak,
but that had no impact, and make -d was not helpful. Was worth a try.

So no spaces in paths, but at least configure can handle the src path.
2024-12-04 20:02:06 +02:00
Avi Halachmi (:avih)
9289c6c5e0 configure: confvars: warn/error on bad key or value
$confvars is not supposed to hold the same key more than once, and
spaces in values won't be parsed correctly. Additionally, it's later
iterated using shell IFS-split - which will also apply globs.

We now abort if the value IFS-splits badly (spaces/glob/empty).

We now warn on duplicates, but still accept them like before.

Example duplicate: --enable-static --disable-static
Example spaces:    --config-foo="bar baz"
Example glob:      --config-foo=" * "

Note that globs currently already expand at  eval opt=\"$opt\"
before we get a chance to test it (but we still detect the spaces).
See commit message of 21272067 (boilerplate var=..) about removing it.

These tests are also performed on values which configure itself adds,
but currently there are no issues with those.

Also, default_conf() now uses confvars_has, which fixes the following:
- False-positive if the key is a substring of existing key or value.
- Incorrect test if the value contains '=' or sh pattern chars *?[] .
No-op, because current default_conf calls don't have such issues.
2024-12-04 18:53:58 +02:00
Avi Halachmi (:avih)
ab6e750bd5 configure: avoid boilerplate: confvars="$confvars ..."
Trivial, but less noisy when reading, and nicer for new code.

The code still adds the value[s] unconditionaly without checking for
duplicates or spaces in values - both are bad, but next commit will.
2024-12-04 18:53:40 +02:00
Avi Halachmi (:avih)
2127206790 configure: avoid boilerplate: var=echo $opt | ...
Add and use "assign_opt" instead of copy-pasting subshell assignment.

Slightly faster, and fixes option values with consecutive spaces,
for instance --libdir='/foo   bar' where previously `echo $opt | ...`
coalesced IFS chars because $opt was unquoted. (this is still very
likely to break, but at least now not at the options parsing).

Unrelated note:

The code does  eval opt=\"$opt\"  for every argument, to "reproduce
autotools behavior" (commit 2e7a1af, 2012-06-12, Thomas Preud'homme).

This is questionable, and not fun (try: --config-x='"; echo "PWNED').
I emailed the author for more info, but didn't get a reply aftre few
days, and without real-world use cases, I think it should be removed.
2024-12-04 18:53:40 +02:00
Avi Halachmi (:avih)
6f4b384e79 configure: avoid non-POSIX: local var=...
The vast majority of shells do support "local", but not all, notably
AT&T ksh (default sh in illumos-based distros and Solaris), but also
some other POSIX-compliant shells, so remove "local".

print_str(), print_num() are modified trivially.

default() now uses standard "Assign Default Value" - same semantics,
and works in all shells (and POSIX).

default_conf() is identical to before, but it had and still has few
minor issues, which will be addressed in a future commit.
2024-12-04 18:52:52 +02:00
Avi Halachmi (:avih)
05ebe494dd configure: avoid non-POSIX: test ... -a/-o ...
Shells do support those, and typically simple forms do work, but
these were removed in POSIX 2024 because they are notoriously hard
to parse correctly, and shells don't always agree on the result.

Instead, use standard forms which all shells support identically.

Extreme high level overview of quotes in POSIX shell:
- WORDs without $... or glob don't need quotes (echo, =, no, x86, ...).
- a=  b=foo  c=$...  and  case $d in ...  all don't need quotes.
- IFS/glob affect command and arguments (not assignments or case..in):
  - IFS only splits direct result of $..., quotes will prevent that.
  - Glob then splits/matches *?[]      and quotes will prevent that.

POSIX "test" (see Application Usage), and shell language (quotes):
  https://pubs.opengroup.org/onlinepubs/9799919799/utilities/test.html
  https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html

My own quick guide:
  https://gist.github.com/avih/6752ad1e20b334b56fef120cd09c766e
2024-12-04 18:52:35 +02:00
Avi Halachmi (:avih)
cea857bf73 configure: win32: don't fail when building using tcc
Commit 729918e ("make: make shorter command lines", 2024-11-21) added
"-static" when $cc_name is gcc to statically link with the mingw gcc
runtime, so that tcc.exe won't depend on additional non-system dlls.

However, $cc_name is still the default value at this time - gcc,
so "-static" was unconditional, and it failed if $cc is tcc (msvcrt).

This commit instead checks the already known $cc, and restores the
ability to build tcc using tcc (if "$cc" doesn't contain "gcc").
2024-12-04 18:21:46 +02:00
grischka
729918ef35 make: make shorter command lines
Put former NATIVE_DEFINES into config.h.  Such tcc can be run
and tested directly from source more easily, like for example:

    tcc -run tcc.c -B. -run test.c

Also:
- tccelf.c: cleanup
- tccpp.c: avoid stupid clang warning
- configure: reduce -Wno- switches
- tcc.h: inline wait/post_sem()
- tccpe.c: simplify import (assume STT_NOTYPE is function)
2024-11-30 20:05:02 +01:00
grischka
4b0402825e tccgen: C2x 'enum <tag> : <type> ...'
accept the new C2x typed enums (seems new android-NDK
headers are using that now)
2024-11-30 20:04:28 +01:00
Avi Halachmi (:avih)
249a0b6b60 win32: add minimal mingw header shellapi.h
This is a very stripped down version[1], with only CommandLineToArgvW
(typically used with GetCommandLineW() - which we already have),
ShellExecute and FindExecutable, which don't require any new structs,
and where used constants already exist at our winuser.h .

Pretty cheap, and hopefully covers some meaningful new use cases[2].

Requires linking with -lshell32 .

[1] original full version:
http://download.savannah.nongnu.org/releases/tinycc/winapi-full-for-0.9.27.zip

[2] Can now build "less" for windows - https://github.com/gwsw/less/ .
Add -luser32 to LIBS at Makefile.wng (mingw makefile), then (gnu make):
  make -f Makefile.wng CC=tcc less.exe
2024-11-30 16:29:15 +02:00
Avi Halachmi (:avih)
085e029f08 fix typos in comments 2024-11-22 15:33:12 +02:00
Avi Halachmi (:avih)
1cf33feb0f w32: improve quoting when spawning cross-compiler
The previous code had few issues:
- Didn't quote an empty string.
- Didn't quote if the string contains tabs.
- Didn't take into account existing backslashes at the string.

E.g. previously broken (in POSIX sh, like cygwin or busybox-w32):
- tcc -m 32 test.c -D 'CSTR="foo'$'\t''bar"' (wrongly rejected by tcc).
- tcc -m 32 test.c -D 'CSTR="foo\"bar"'  (incorrect CSTR at test.c).

Both issues are fixed with the new code, and presumably any others.

The empty/tabs issues could be fixed within the current code, but the
backslashes issue is not worth shoehorning it, so this is a rewrite.
2024-11-22 15:11:05 +02:00
Avi Halachmi (:avih)
a6ef31823b tcc -ar options: use strchr, strpbrk (trivial, no-op)
I happened to bump into thsese, but I didn't try to review the file,
and there may be other places which could be similarly improved.

This is originally my suboptimal code from commit 100f94be
(tiny_libmaker: more robust arguments interpretation), so, a bit late,
but let's improve it anyway.
2024-11-22 00:06:44 +02:00
checkroom
ef7e84454e Fixing preprocessor edge case preventing building with meson https://github.com/KaruroChori/tcc-vs 2024-11-20 01:39:04 +00:00
Avi Halachmi (:avih)
cff81434a5 win32: 32 bit: allow 64 bit time via __MINGW_USE_VC2005_COMPAT
Before VC2005, the time macros (time, time_t, localtime, etc) were
32 bit on 32 bit platforms, but they became 64 in VC2005.
This works even on XP 32 (_time64 etc do exist in XP32 - and in tcc).

However, tv_sec in struct timeval (which for msvc is in winsock2.h)
remains 32 bit to this day on 32 bit platforms, and dlls which were
not recompiled remain with time 32, possibly at the API boundary.

Due to these, and maybe more, mingw w64 decided to keep the time
macros 32 bit on 32 bit platforms, with __MINGW_USE_VC2005_COMPAT
override (which does nothing in mingw w64 except time -> time64).

It's not perfect, but it allows some existing code to easily switch
to 64 bit time without redefining time etc, e.g. used by libressl:
  https://github.com/libressl/portable/blob/master/README.mingw.md

Before, it was impossible to enable the 64 bit time macros in tcc 32.

This commit adds support for __MINGW_USE_VC2005_COMPAT in tcc as well,
which, like in mingw w64, affects only the 32->64 time macros, and is
a cheap way to get 64 bit time in existing code in some 32 bit apps.

The additional #ifndef _USE_32BIT_TIME_T is unrelated to the override,
and avoids a warning (and nothing else) when the code explicitly
defines it - which is allowed in MSVC, and also guarded in mingw w64.

Relevant current quote from the libressl link above:
------- >8 ---------

Why the -D__MINGW_USE_VC2005_COMPAT flag on 32-bit systems?

An ABI change introduced with Microsoft Visual C++ 2005 (also known as
Visual C++ 8.0) switched time_t from 32-bit to 64-bit. It is important
to build LibreSSL with 64-bit time_t whenever possible, because 32-bit
time_t is unable to represent times past 2038 (this is commonly known
as the Y2K38 problem).

If LibreSSL is built with 32-bit time_t, when verifying a certificate
whose expiry date is set past 19 January 2038, it will be unable to
tell if the certificate has expired or not, and thus take the safe
stance and reject it.

In order to avoid this, you need to build LibreSSL (and everything
that links with it) with the -D__MINGW_USE_VC2005_COMPAT flag. This
tells MinGW-w64 to use the new ABI.

64-bit systems always have a 64-bit time_t and are not affected by
this problem.
2024-11-18 15:45:30 +02:00
Avi Halachmi (:avih)
00b29f49a9 win32: mingw headers: mainly add LOAD_LIBRARY* values
The LOAD_LIBRARY_* constants allow safer and more controlled load.

The others in winnt.h and wincon.h are relatively minor.
2024-11-18 15:44:14 +02:00
grischka
dd2e5f8b06 tccelf: cleanup sort_sections() & etc. fixes
with -Wl,-oformat=binary, executable code should come first.
(for linux kernel image for example)

Also:
- simplify RELRO sections: create them as readonly, but add
  SHF_WRITE flag later when needed (i.e. relocations do exist)
- tcc.h etc: exclude eh_frames on non-elf platforms
- tccelf.c:tcc_load_object_file(): don't load debug sections when
  linking without -g (special dwarf case in relocate_section()
  wont work when dwlo/hi were not initialized).
- tcc.c: avoid loop if something fails (ret < 0) without message
  (while failing without message should not happen either)
- tccelf.c:tcc_load_alacarte: give message
- tccpp.c: treat '# 123xyz' in asm file as comment
- lib/Makefile: cleanup
- libtcc.c: tcc_add_library(): fallback to try filename as is
  (also remove tcc_add_library_err())
2024-11-17 21:39:38 +01:00
grischka
3eb6352c52 tcc -fgnu89-inline -fno-asynchronous-unwind-tables
-fgnu89-inline: 'extern inline' like 'static inline'
-fno-asynchronous-unwind-tables: don't emit eh_frames
2024-11-17 21:27:23 +01:00
grischka
f24727b6bb tcc -freverse-funcargs (reverse evaluation)
patch originally made to prove correctness (comparing stages)
with tinycc compiling gcc 2.95.3 which would assign registers
differently (but still correctly) when compiled with tcc without
this option).

Also: fixes get_temp_local_var() which on 32-bit systems
happened to return a temporary location that was still
in use because its offset was changed on the vstack
(incremented by four in gv() to load the second register
of a long long).

Also: optimize vrot-t/b (slightly) by using one memmove
instead of moving elements one by one in a loop.
2024-11-17 21:04:29 +01:00
grischka
c717bac6e3 tccgen: show useful line number with duplicate switch-case
- output correct line number with "error: duplicate case value"
- libtcc.c:error1(): support specific line numbers with "%i:"
       tcc_error("%i:message ...", line_num, ...);
Also:
- simplify signed/unsigned switch compare
- optimize implicit case ranges such as
      case 1: case 2: case 3: ...
- simplify llong constant propagation in gen_opic()
- rename Sym.ncl to Sym.cleanup_func
2024-11-17 20:56:12 +01:00
herman ten brugge
f0cd0fbe1b Print bound region when bound checking error occurs 2024-11-09 08:34:10 +01:00
herman ten brugge
233e22f23d Fix compile problem on windows 2024-11-09 08:24:58 +01:00
herman ten brugge
322c4dc275 Add support for backtrace()
This requires adding .eh_frame and .eh_frame_hdr sections.

There are 3 new functions to setup the sections:
tcc_eh_frame_start: create cie in .eh_frame
tcc_debug_frame_end: add fde in .eh_frame for every function
tcc_eh_frame_hdr: create .eh_frame_hdr

The PT_GNU_EH_FRAME header is created.

The dwarf read functions are moved from tccrun.c to tcc.h

The backtrace() function is not supported on all targets.
windows, apple, bsd and arm are disabled.
arm uses its own sections .ARM.extab and .ARM.exidx.
2024-11-09 08:04:45 +01:00
John Nunley
a21b5f1fd7
x86_64-asm: support endbr64 instruction
endbr64 has no operand but comes with a ModR/M byte. Handle it in the
same way as *fence instructions.

Co-authored-by: Yao Zi <ziyao@disroot.org>
Signed-off-by: Yao Zi <ziyao@disroot.org>
Signed-off-by: John Nunley <dev@notgull.net>
2024-10-27 15:33:23 -07:00
John Nunley
6acf301e77
x86_64-asm.h: support callq for better compat
It has the same effect as call.

Co-authored-by: Yao Zi <ziyao@disroot.org>
Signed-off-by: Yao Zi <ziyao@disroot.org>
Signed-off-by: John Nunley <dev@notgull.net>
2024-10-27 15:27:00 -07:00
tuxcrafting
50cfe1141b fix -section-alignment smaller than ELF header size 2024-10-24 13:02:28 +03:00
Avi Halachmi (:avih)
d9f1836124 win32: tcc-win32.txt: fixup 2 mingw includes note
Note to self: review few times before pushing next time.
2024-10-23 16:32:49 +03:00
Avi Halachmi (:avih)
c7bf40b958 win32: tcc-win32.txt: fixup mingw includes note 2024-10-23 16:21:05 +03:00
Avi Halachmi (:avih)
4f7b8304df win32: tcc-win32.txt: add note about mingw includes 2024-10-23 16:14:40 +03:00
Avi Halachmi (:avih)
45788e91ca win32: make #include <unistd.h> work
We already have sys/unistd.h, but the standard place for it is at
the include root, so make that work too, but keep sys/unistd.h for
backward compatibility.
2024-10-23 14:58:41 +03:00
Avi Halachmi (:avih)
e1c8d3a1e6 win32: include/sys/types.h: add useconds_t
Required by unistd.h in the auxiliary package:
  winapi-full-for-0.9.27.zip
2024-10-23 14:48:50 +03:00
grischka
9fb89c23d0 tcc -ar: pad archive member position to even
Since commit 45cff8f0 tcc eventually generates object files
of non-even size.

tccelf.c:
- check ARFMAG for better invalid archive detection
- file_offset needs to be aligned, not the size (just a nitpick)
lib/Makefile:
- remake everything when tcc did change
2024-10-22 21:38:31 +02:00
herman ten brugge
d7f9166ab5 Fix last commit. 2024-10-20 11:05:10 +02:00
herman ten brugge
5a467ddc98 Move sort_syms to avoid linker error
compiling with tcc and linking with gcc gives error:

tcc -c a.c
gcc a.o
usr/bin/ld: a.o: .symtab local symbol at index 0 (>= sh_info of 0)
/usr/bin/ld: a.o: error adding symbols: bad value
collect2: error: ld returned 1 exit status

Solved by moving call to sort_syms.
2024-10-20 10:57:50 +02:00
Steffen Nurpmeso
7a6f3fded4 include/tccdefs.h: has_atttribute -> attribute (fixes 45cff8f03f) 2024-10-20 04:41:13 +02:00
grischka
45cff8f03f tccelf.c: write section headers before sections
also avoid zero lenght PT_LOAD segments (which some musl
loaders seem to dislike)

Also:
- tccasm.c: support .section with flags: .section .xyz,"wx"
  (fixes e4d874d88a)
- tccgen,c:  add __builtin_unreachable()
- tccdefs.h: #define __has_attribute(x) 0
- tcc.c: tidy help for -std
- tcctools.c/execvp_win32: quote strings more correctly
- x86_64-gen.c:win32: set unwind begin-address to function-start
- github action: add aarch64-osx (M1) & i386-win32
- configure: consider 32-bit build on MSYS64 native
2024-10-13 23:55:32 +02:00
Ben Noordhuis
c21576f8a3 Emit better x86_64 asm for constant loads
Instead of always emitting movabs, emit a regular mov or a xor.
Slims down sequences like:

    movabs $0,%rax
    mov %rsi,%rax

To:

    xor %eax,%eax  // also zeroes upper word
    mov %rsi,%rax

Future work is to just emit:

    xor %esi,%esi
2024-10-10 22:48:56 +02:00
Petr Skocik
b668b72b06 recognize -std=gnu11 and treat it the same as -std=c11 2024-10-09 08:22:53 +02:00
Meng Zhuo
3110f69e4e update Github action runner macOS to 12 2024-10-08 17:51:34 +08:00
Boian Berberov
3ead10dd94 fix: respect CFLAGS from environment, or set defaults 2024-09-27 12:26:21 -06:00
Guest0x0
b8b6a5fd7b fix UB in constant folding of double -> signed integer conversion 2024-09-14 06:17:23 +00:00
Maxim Logaev
12acbf3e92 tccdbg.c: DW_AT_language now matches the -std option
Signed-off-by: Maxim Logaev <maxlogaev@proton.me>
2024-08-20 17:58:50 +03:00
noneofyourbusiness
3d963aebcd
Relicensing TinyCC 2024-08-11 15:18:36 +02:00
noneofyourbusiness
3415dec979
riscv64-tok.h: don't export internal macros 2024-08-11 00:41:21 +02:00
noneofyourbusiness
3d65c596a2
tcc -dumpmachine: output -musl instead of -gnu when TCC_MUSL is defined 2024-08-11 00:18:21 +02:00
Jonathan M. Wilbur
1cee0908d2 fix: tests broken by use of assembly 2024-07-31 04:31:48 -04:00
Jonathan M. Wilbur
f15008da05 fix: previous two commits 2024-07-31 04:15:45 -04:00
Jonathan M. Wilbur
e4d874d88a fix: code in non-executable ELF sections 2024-07-30 10:33:44 -04:00
Jonathan M. Wilbur
c85eface68 feat: treat unknown macros with arguments as undefined 2024-07-30 08:54:00 -04:00
grischka
08a4c52de3 tccpp: tcc_warning("extra tokens after directive")
with stuff like
    #endif int x;
Also fix
    /* */ #else
Also:
- search_cached_include(): search for file->true_filename
- tccasm.c: avoid crash with .file
2024-06-11 14:42:56 +02:00
grischka
6b78e561c8 div fixes
- Makefile: don't produce unknown targets
- libtcc.c: tcc_set_linker(): improve parser
- tcc.h: tcc_internal_error(): don't record __FILE__ (for privacy reasons)
- tccgen.c:
  - reject pointer + float operation
  - use 'int level' for builtin_frame/return_address
  - save_regs(): remove VT_ARRAY (confuses riscv64-gen)
- tccpe.c: store just basename of loaded dlls (rather than full path)
- tccpp.c: remove unused TAL defines
- *-link.c: add missing ST_FUNC
- i386-gen.c: fix thiscall
- riscv64-asm.c/arm-asm.c: stay simple C89
  - avoid .designators, decl after statement
  - avoid multiple instances of same static const objects
  - use skip() instead of next() & expect()
  - use cstr_printf() instead of snprintf() & cstr_cat()
  - tcc_error(), expect(): never return
2024-06-11 14:26:34 +02:00
Gynt
3b943bec5d implemented thiscall by copying logic from fastcall
implemented improved thiscall by using mov ecx instead of pop ecx

include __thiscall and __thiscall__ as aliases

remove fake line in test
2024-06-03 13:56:32 +02:00
herman ten brugge
8cd21e91cc Address of solved for riscv64
A character size load was used instead of pointer size some times.
2024-06-01 07:29:28 +02:00
Avi Halachmi (:avih)
da5aa7d7a8 win32: wincon.h: support more console mode flags
Mainly VT modes (win 10+), quick-edit, insert.
2024-05-12 10:51:20 +03:00
Ekaitz Zarraga
0aca861194 fixup! riscv: Implement large addend for global address
Use `t1` instead of `t0` for the cases when `rr` is not set so `t0` is
used by default and this happens:

    lui t0, XXX
    add t0, t0, t0

Instead, now we do:

    lui t1, XXX
    add t0, t0, t1
2024-04-28 00:15:23 +02:00
Ekaitz Zarraga
8baadb3b55 riscv: asm: implement j offset 2024-04-25 15:13:21 +02:00
Ekaitz Zarraga
159776304f riscv: asm: Add branch to label 2024-04-24 00:54:51 +02:00
Ekaitz Zarraga
671d03f944 riscv: Add full fence instruction support
This commit adds support for `fence`'s predecessor and successor
arguments.
2024-04-23 15:10:08 +02:00
Ekaitz Zarraga
c994068175 riscv: asm: Add load-reserved and store-conditional
Add Atomic instructions `ld` and `sc` in their 32 bit and 64 bit
versions.
2024-04-23 12:05:05 +02:00
Ekaitz Zarraga
0703df1a6a Fix Extended Asm ignored constraints
This commit fixes the case where the register of for the Extended Asm
input or output is known. Before this commit, the following case:

  register long __a0 asm ("a0") = one;
  asm volatile (
       "ecall\n\t"
       : "+r" (__a0) // NOTE the +r here
  );

Didn't treat `a0` as an input+output register (+ contraint) as the code
skipped the constraint processing when the register was already chosen
(instead of allocated later).

This issue comes from f081acbfba, that was
taken as a reference in every other Extended Assembler implementation.
2024-04-16 02:47:56 +02:00
herman ten brugge
4944f509c3 riscv: Avoid some compiler warnings 2024-04-13 16:26:12 +02:00
Ekaitz Zarraga
6b3cfdd025 riscv: Add extended assembly support
NOTE: In order to be able to deal with general-purpose vs floating-point
registers, this commit adds a flag in the 6th bit of the register. If
set, it means the register is a floating-point one. This affects all the
assembler.
2024-04-09 00:19:41 +02:00
Ekaitz Zarraga
e02eec6bde riscv: fix jal: fix reloc and parsing 2024-03-27 11:50:02 +01:00
Ekaitz Zarraga
0239133488 fixup! riscv: Add .option assembly directive (unimp) 2024-03-23 12:32:32 +01:00
Ekaitz Zarraga
cbe70fa629 riscv: Add .option assembly directive (unimp) 2024-03-21 13:33:27 +01:00
Ekaitz Zarraga
618c173421 riscv: libtcc1.c support some builtins for __riscv 2024-03-21 13:33:27 +01:00
Ekaitz Zarraga
3782da8d0c riscv: Support $ in identifiers in extended asm.
Needed for using `__global_pointer$`.
$ don't have special meaning in RISC-V assembly.
2024-03-21 13:33:27 +01:00
Ekaitz Zarraga
e2d8eb3d1c riscv: jal: Add pseudo instruction support 2024-03-21 13:33:27 +01:00
Ekaitz Zarraga
409007c9d5 riscv: jalr: implement pseudo and parse like GAS 2024-03-21 13:33:27 +01:00
Ekaitz Zarraga
8bfef6ab18 riscv: Add pseudoinstructions
call, tail, jump, jr, mv, not, neg, negw, seqz, snez, sltz, sgtz, bnez,
beqz, blez, bgez, bltz, bgtz, li
2024-03-21 13:33:25 +01:00
Ekaitz Zarraga
8cbbd2b88a riscv: Use GAS syntax for loads/stores:
Before:
    ld rd, rs, imm
    sd rs1, rs2, imm

Now:
    ld rd, imm(rs)
    sd rs2, imm(rs1)

NOTES: Just as in GAS:
    - In stores the register order is swapped
    - imm is optional
    - when imm is not included parenthesis can be removed
2024-03-19 12:38:21 +01:00
Ekaitz Zarraga
019d10fc12 riscv: Move operand parsing to a separate function 2024-03-19 12:38:21 +01:00
grischka
2b0a663df9 libtcc usability improvements
- tccgen.c: cleanup switch data etc. after errors (*)
- tccpe.c: faster get_dllexports (*)
- tccpe.c: support -Wl,-e[ntry]=... (*)
- libtcc.c: win32: use ANSI functions (GetModuleFileNameA etc.)
- tccrun.c: be nice to tcc-0.9.26 ("struct/enum already defined")
- tccpp.c: be nice to tcc-0.9.27's va_start/end macros

(*) suggested by Robert Schlicht
https://lists.gnu.org/archive/html/tinycc-devel/2024-03/msg00012.html
2024-03-13 21:06:01 +01:00
grischka
9d2068c630 tccrun: add option CONFIG_RUNMEM_RO=2
/* 0 = .text rwx  other rw (memory: min 2 pages) */
/* 1 = .text rx   other rw (memory: min 3 pages) */
/* 2 = .text rx  .rdata ro  .data/.bss rw (memory: min 4 pages) */

tcc -vv -run ... shows some info.
Also when compiled with -DMEM_DEBUG:
tcc -bench -run ... shows some memory usage
2024-03-03 21:39:53 +01:00
grischka
ca061f3a96 i386-asm: fix pc-relative label ariths
See test. We need to use 'ind' from later when the address
field of the instruction is put.

Also: fix crash when the substracted symbol is undefined
Also: assume asm-symbols to be lvalues (except func/array)
2024-03-03 19:56:18 +01:00
herman ten brugge
9675c1e245 Use CONFIG_RUNMEM_RO=1 on apple 2024-03-03 06:41:27 +01:00
grischka
42395a1912 tccrun: PAGEALIGN'ed mprotect
the un-mprotect() after run was severly off the limits.

Also in tcc.c:main: do not confuse errors with non-zero
results from tcc_run()
2024-02-29 22:52:02 +01:00
Ekaitz Zarraga
7bc0cb5ba0 riscv: Implement large addend for global address 2024-02-29 19:42:02 +01:00
herman ten brugge
2656f8edcc Fix win64 noreturn problem
On win64 the code would hang in longjump with previous change
2024-02-28 07:37:09 +01:00
herman ten brugge
f9cb198aa8 tccrun: update for apple and openbsd
Apple needs CONFIG_RUNMEM_RO=1
I now only set CONFIG_RUNMEM_RO=0 on _WIN32

Openbsd does not have malloc.h so remove some code

Also fix some warnings when compiling lib with gcc
2024-02-26 07:18:07 +01:00
grischka
4e91d38ddc tccrun: resign from "advanced" system calls (memaligh/gettid)
... let's stay compatible
2024-02-25 19:55:06 +01:00
grischka
d2f8ceac7a tccrun: review last changes
- LIBTCCAPI int tcc_set_backtrace_func(void *ud, ...)
  accept opaque user data pointer,
- tcc -vv -run... : show section info
- use memalign() to allocate runtime memory
- printline_/dwarf : pass output to parent function
- tccpe.c : fix -nostdlib -run
- --config-backtrace=no : make it work again
2024-02-19 17:45:44 +01:00
grischka
c88b19966c tccrun: exit() via rt_longjmp()
- new LIBTCC API tcc_setjmp() to allow longjmps & signals
  from compiled code back to libtcc per TCCState
- new LIBTCC API tcc_set_backtrace_func() to handle backtrace output
- move c/dtor/atexit stuff to runtime (lib/runmain.c)
- move bt-log.o into libtcc1.a
- add timeouts to github action (beware, it did happen to hang
  infinitely in the signal handler at some point)
2024-02-15 18:45:49 +01:00
herman ten brugge
8d8d75ca75 Allow tcc to run with bounds checking enabled
tcc failed to run with bounds checking enabled because the functions
rt_wait_sem, rt_post_sem and _rt_error where defined twice.
This is solved by making them weak in tccrun.c

Also a nested lock was present when setting TCC_BOUNDS_PRINT_CALLS=1
This is solved in lib/bt-exe.c by moving lock/unlock code.

Also added a testcase in tests/Makefile to test tcc with bounds
checking enabled.
2024-02-15 07:17:15 +01:00
Detlef Riekenberg
f2e8b2ad79 bcheck: fix argument order for memalign
Spotted by George Sedov on the mailing list.

The bug was in the tcc source since >20 years:
https://repo.or.cz/tinycc.git?a=commit;h=ad28d4c5b03da27dc0381afb58f255d49962cca0

manpage for memalign:
https://linux.die.net/man/3/memalign

--
Regards ... Detlef
2024-02-15 00:56:54 +01:00
grischka
a7cd016d71 tccrun: 'tcc_relocate()' twice no longer supported
- abort with notice when tcc_relocate() is called with the
  former two-step method
- support backtrace & bcheck not only with tcc_run() but also
  for directly called functions from tcc_get_symbol(); enable
  witn 'tcc_set_options("-bt/-b");'
- move struct rt_context and debug sections into compiled code
  for TCC_OUTPUT_MEMORY also
- protect access (g_rc) with semaphore
Also:
- add armv7/aarch4/riscv64 github tests (qemu emulated)
- win32/build-tcc.bat: build cross compiler only with -x
2024-02-14 00:56:36 +01:00
grischka
7b9f19eaab tccpp: macro cleanup
- remove TOK_NOSUBST, mark the token itself instead
- get_tok_str(); mask out SYM_FIELD & update uses
- next(): optimize (~5% faster with tcc -E)
- tok_flags: remove some redundancy
- parse_define(): do not remove spaces around '##' and after '#'
    and mark macros with '##' as MACRO_JOIN to avoid unnecessary
    call to macro_twosharps(mstr):
- next_nomacro(): removed, next_nomacro1(): renamed to next_nomacro()
- next_argstream(): cleanup & new function peek_file()
- macro_subst_tok(): handle special macros (__DATE__ etc.)
  like normal macros if they are #defined
- -DPP_DEBUG : more structured output
- pp_error(): better preprocessor expression error message
- tcctok.h: sort basic keywords (somehow)
- testspp/Makefile: generate .expect with 'make testspp.##+'
- tcc.c: tcc -E -o file : put unixy LFs also on windows
2024-02-09 18:38:14 +01:00
grischka
b671fc0594 LIBTCCAPI tcc_relocate(s) : REMOVED 2nd argument
removed second argument for tcc_relocate(s). previous
'TCC_RELOCATE_AUTO' is now default and only behavior.

Rationale:
  In the past, the option to compile into memory provided by the
  user was introduced because only one TCCState could exist at a time.

  This is no longer a limitation.  As such it is also possible now to
  keep any number of compiled code snippets around together with their
  state in order to run them as needed.

- Also
  - LIBTCCAPI tcc_get_error_func/opaque() removed
  - tccrun/SELINUX: switch rx/rw mappings such that rx comes first
    (risc64-link.c:relocate_plt() does not like got < plt)
  - tcc_relocate_ex(): free local symbols and obsolete sections
    to reduce memory after tcc_relocate()
2024-02-09 13:38:27 +01:00
herman ten brugge
a0ab99169e Pointer diff should use signed size 2024-02-09 08:35:32 +01:00
kbkpbot
76d605192d add MemoryBarrier marco define; tested gcc msvc 2024-02-08 11:13:51 +08:00
herman ten brugge
cd6ad857cf Fix default_reallocator declaration 2024-02-07 07:01:36 +01:00
Eric Raible
be6584e2b9 Allow use of a custom allocator in libtcc
When using libtcc it's reasonable to be able to use the application's
memory allocator for all allocations, including tcc_new(), and including
#define MEM_DEBUG

Ideally the allocator would be stored in the TCCState, like TCCErrorFunc.
That would imply a new API tcc_new_with_allocator(), but more importantly
would require all uses of tcc_malloc(x) to be changed to s->tcc_malloc(x).
That's a non-starter in my book.

Instead I refactored the memory management code so that all allocations
flow through tcc_realloc().  Which simply calls a function pointer, the
default value of which is the previous tcc_realloc().

It then becomess trivial to install a new allocator with the new function:
LIBTCCAPI void tcc_set_realloc(TCCReallocFunc realloc);

The resulting code adds the trivial cost of an additional function call
per allocation/free.  It also doesn't distinguish between malloc failure
and realloc failure, but since both just fprintf then exit() that seems
unimportant to me.

On the plus side the preprocessor magic is much more clear.  The diffs
don't hightlight that, but take a look at the result to see if you agree.

All tests passed on my x86 linux box.
2024-02-06 20:01:18 -08:00
kbkpbot
105d70f7b4 atomic_load/atomic_store : to ensure return the latest value, should we add a memory barrier here?
If have no these memory barriers, sometime it will cause bug in multiple threads program.
2024-02-05 08:37:41 +08:00
grischka
da0d43903b review recent commits
tccpp.c:
 - revert "Preprocessor fix + new testcase"
   Fix was not a fix and nobody could understand the test.
   This reverts 6379f2ee76
 - better fix and add new test (pp/18.c)

tccgen.c:
 - remove global variables 'in_sizeof', 'constant_p'
 - rework comma expression (gexpr())
 - merge func/data 'alias_target' codes
   (See 08c777053c)
 - move call to do_Static_assert()
 - better error: "expression expected before '%s'"
 - fix "statement after label"
    - remove unnecessary second parameter to block()
    - remove unnecessary call to decl()
    - revert changes to old C89 test file
    See 7f0a28f6ca

tccelf.c:
 - rework "...make undefined global symbol STT_NOTYPE"
   (See f44060f8fc)
 - move tccelf_add_crtbegin() from libtcc.c

tcctest:
 - unfix K&R fix (keep old look of K&R functions)

tccrun.c:
 - exit(0) returns 0

libtcc.c:
 - move #defines for -dumpmachine
 - more explicit error "file not found"
   (as opposed to error while loading file)

tccpe.c, x86_64-gen.c, i386-asm.c, tccasm.c:
 - use R_X86_64_PLT32 for functions on x86_64-win32

tccdefs.h
 - empty #defines for _Nonnull, __has_builtin(), etc.

configure:
 - Simpler "macOS .dylib ... VERSION letters."
   (See 6b967b1285)

Makefile:
 - macOS version also
 - add cross searchpaths for packages

build.yml:
 - disable codesign on macos-11 (doesn't seem to work)
2024-02-04 18:18:40 +01:00
Ekaitz Zarraga
6426cc3384 Revert "riscv64-gen: Fix load and store type_size usage"
It was already contemplated by c81116e29a.

This reverts commit c7263571d2.
2024-01-30 17:41:26 +01:00
Ekaitz Zarraga
c7263571d2 riscv64-gen: Fix load and store type_size usage
In `load` and `store` RISC-V gen used `type_size` to retrieve the size
of the types being moved around, the problem with that function is it
tries to obtain internal information of the type. When using `type_size`
with a `char *` it returns 1, and emits a `lb` instruction when using a
conditional expression like so (but probably also in other cases):

    char *a, *b;
    b = "hello";
    a = x ? b : "" ;                // this emits an `lb`

That `lb` clobbers the pointer, only loading the latest byte of it:

    // if `b` was, say: 0x1f822e
    a = b;
    // now `a` is 0x00002e

NOTE: We spotted this when building make-3.82, in `init_switches`
      function in the `main.c` file. This error made `make` unable to
      run long options like `make --help` (segfault when doing the
      `strlen` later)

This happens because a `char *` is internally stored as a `char[1]` or
something similar, it's result is the size of a `char` (1) times the
size of the array `1`. This is not what we want, we are copying the
pointer, not the array itself. Using `type_size` for this is not
appropriate even if it works for some cases.

If the conditional expression is rewritten to imperative style using an
`if` it works properly, so it might be related with the fact the pointer
is `load`ed to a register.

`load` and `store` should only work with integral types, so reading the
size of the array is not useful. This commit creates a simpler version
of this function that only reads the integral type of what's working
with: char * is considered just a pointer. So it makes an `ld` instead,
and the code above works.
2024-01-29 11:09:59 +01:00
herman ten brugge
7f0a28f6ca C23: Implement declaration after label
Only allow declaration after label if it is inside '{...}'
2024-01-28 07:18:12 +01:00
herman ten brugge
7d1bbc80d4 Update for clang
Clang also removed K&R support so define IMPLICIT_INT.
Fix clang warning in lib/bt-log.c
2024-01-17 07:07:48 +01:00
herman ten brugge
0059d89c0f Prepare for gcc 14
Gcc 14 reports -Wimplicit-int errors because old K&R is not supported
any more.
2024-01-16 22:21:19 +01:00
herman ten brugge
bbe2e5a421 Allow declarations in case statement
This now works:

 case 1:
    int z = 123;
    break;
2024-01-16 07:51:56 +01:00
Andrius Štikonas
04365dd4c9 riscv64-asm.c: fix assembly instruction with negative immediate offsets.
This fixes expressions like ld a0, s0, -24 that regressed in
d87801bd50
2024-01-12 21:09:21 +00:00
herman ten brugge
6120656cbf Rewrite gexpr a bit 2024-01-08 11:34:47 +01:00
herman ten brugge
2701dcfb06 Add some relocations to riscv64-link.c
dlltest failed on a riscv machine.
2024-01-07 07:45:31 +01:00
herman ten brugge
c13bbb5cb5 Add type promotion in comma expression and update testcase 94 2024-01-06 07:54:34 +01:00
herman ten brugge
6379f2ee76 Preprocessor fix + new testcase 2023-12-29 09:08:25 +01:00
herman ten brugge
48798969c5 Update riscv64-asm prototypes 2023-12-16 12:28:19 +01:00
noneofyourbusiness
ada17a08eb
riscv64-asm.c: add support for calculating addresses of symbols
add some pseudoinstructions
riscv64-tok.h: add pseudoinstructions from tables 25.{2,3}
2023-12-12 09:44:37 +01:00
noneofyourbusiness
b390feec6d
riscv64-asm.c: add Zicsr registers 2023-12-10 15:24:25 +01:00
noneofyourbusiness
5dc241fee1
riscv64-tok.h: add Zicsr pseudoinstructions, registers 2023-12-10 15:22:41 +01:00
noneofyourbusiness
3b3c9412ac
riscv64-asm.c: implement Zicsr extension 2023-12-09 14:32:14 +01:00
noneofyourbusiness
279dbb94e2
riscv64-asm.c: correct check for 12-bit immediate
asm_emit_cj: correct check for offset size
2023-12-09 01:00:16 +01:00
noneofyourbusiness
275dfbea20
riscv64-asm.c: implement M extension 2023-12-08 22:48:43 +01:00
noneofyourbusiness
c71415b543
riscv64 elf flags should be configurable 2023-12-08 17:08:03 +01:00
noneofyourbusiness
d87801bd50
riscv64-asm.c: implement C extension
add nop
fix asm_emit_i immediate check (negative offsets were missing)
fix check for IM12S
remove non-existent instructions (example: slli64 is just slli with imm=0)
2023-12-08 17:07:06 +01:00
noneofyourbusiness
81a32ec305
riscv64-asm.c: asm_emit_j: correct check of immediate 2023-12-02 17:08:05 +01:00
Reimar Döffinger
0655fd9637 configure: enable codesign by default on macOS.
It is useful for the default configuration to just
work out of the box and pass tests instead of crashing
in unexplained ways.
2023-11-27 20:17:52 +01:00
Reimar Döffinger
c45cb650fc tcctools.c: reduce duplicated code for -MP option.
Generate list of escaped dependencies as a separate
first step.
2023-11-27 20:17:21 +01:00
noneofyourbusiness
70328621f1
riscv64-asm.c: added asm_emit_j (J-type), changed jal to J-type
additionally added a comment about B-type instruction format
2023-11-27 09:15:32 +01:00
Rob Pilling
fb164e0ab4 Error out for incomplete type initialisation 2023-11-26 09:29:06 +00:00
herman ten brugge
be8f894710 Check for errors before codesign 2023-11-08 21:08:54 +01:00
herman ten brugge
fc8c01861b Fix STT_NOTYPE problem on win32
Since 'make undefined global symbol STT_NOTYPE' change win32 code
did not build any more.
2023-11-08 21:03:10 +01:00
herman ten brugge
ded713e90d Ignore as_needed in ld_add_file_list
After the change to DT_NEEDED I get warnings for some functions.
The reason is that libc.so on my machine contains:
GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a  AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) )

Before the change to DT_NEEDED we solved the symbols because the
/lib64/libc.so.6 file has as DT_NEEDED set for ld-linux-x86-64.so.2
The above AS_NEEDED section was not followed so symbols in this
file gives a warning.
Currently fixed by including AS_NEEDED files.
2023-11-08 19:58:26 +01:00
herman ten brugge
0f29dbcfd5 Update do_debug handling
Make options '-g -b' and '-b -g' set -g2 in both cases.
2023-11-08 19:52:13 +01:00
herman ten brugge
bf928f3f4f Allow libtcc1-usegcc in lib/Makefile 2023-11-08 19:48:39 +01:00
herman ten brugge
be8cded098 Allow make tcov-test on bsd targets 2023-11-08 19:45:29 +01:00
Steffen Nurpmeso
2c1c20a48c Relicensing TinyCC 2023-10-31 22:59:44 +01:00
Reimar Döffinger
36f53cdc3b Revert "tests: Add support for codesigning command."
This reverts commit ece74ceaaf.

codesigning is already supported via --config-codesign.
This patch actually broke testing for tcc builds with
that set.
2023-10-30 19:08:57 +01:00
Reimar Döffinger
b7c732f01c tcctools: delete created ar file on error.
Leaving 0-sized files around might confuse the build system.
2023-10-29 18:13:19 +01:00
Reimar Döffinger
a473473fed stdatomic.h: Add ATOMIC_VAR_INIT macro. 2023-10-29 18:12:31 +01:00
Reimar Döffinger
ece74ceaaf tests: Add support for codesigning command.
Allows running the tests out-of-the-box on macOS.
Also delete *.dylib in tests2 dir on "make clean".
One remaining issue on macOS 14.1 is that the
-undefined warning option no longer works,
thus breaking test3 and test1b.
2023-10-29 17:06:59 +01:00
Reimar Döffinger
32ac23656f Add support for -dumpmachine option.
Better compatibility with some build systems assuming gcc.
2023-10-29 15:55:16 +01:00
Reimar Döffinger
7a53029e4d Add -MP option. 2023-10-29 15:31:58 +01:00
Reimar Döffinger
1bfed06c2a Relicensing TinyCC 2023-10-29 14:53:06 +01:00
Reimar Döffinger
e9aa113240 tccdefs.h: Apple target requires __has_builtin definition.
Note: I have not been able to create working binaries on
macOS 14.1 so far, but at least tcc compiles and produces
binaries now...
2023-10-29 14:45:19 +01:00
Reimar Döffinger
fd775d941d arm64-gen.c: Add __AARCH64EL__ target_machine_defs.
The Python headers require __AARCH64EL__ to be defined.
Also simplify ifdef to avoid duplicating __aarch64__ entry.
2023-10-29 14:36:11 +01:00
Detlef Riekenberg
32c4df1497 tccelf: Do not load all referenced libraries when linking a library
Recursive loading of all references can break linking of libraries
(Example: building of netbsd-curses)

Thanks grischka, Michael and Herman for the comments.

--
Regards ... Detlef
2023-10-26 17:51:30 +02:00
Ben C
6b967b1285 Fix macOS .dylib build when VERSION contains letters.
macOS builds with --disable-static fail to link if the version number
contains letters because of the -current_version and
-compatibility_version arguments (current version is 0.9.28rc).

This commit adds a new MACOS_DYLIB_VERSION variable to config.mak for
builds that target macOS. It has no impact on other targets.
2023-10-25 22:38:07 -04:00
Sylvain BERTRAND
f44060f8fc ELF Relocatable: make undefined global symbol STT_NOTYPE
If undefined global symbols in ELF Relocatable files are not of
type STT_NOTYPE, it will confuse binutils bfd and corrupt product
files.
2023-10-24 18:13:39 +00:00
Petr Skocik
08c777053c Support aliasing static global nonfunction objects
Enables code such as:

    #undef NDEBUG
    #include <assert.h>
    #include <stdint.h>
    static int st_x = 42;
    static int st_x_ __attribute((alias("st_x")));
    int main(void){ assert((uintptr_t)&st_x == (uintptr_t)&st_x_); }

which would previously fail with no compiler warnings. The limitation of
this is that the alias must be done (or redone) after an actual definition.
An alias done right after a later overridden tentative declaration won't
work (sufficient for my use case).
2023-10-08 19:08:20 +02:00
Eric Raible
b214fb6ed3 Produce better error message on malformed while loop
echo "void bugged() { do {} }" | tcc -run -
now produces the sensible:  -:1: error: 'while' expected (got "}")

I believe (but am far from sure) that the additional use of &tokc is ok.
2023-10-03 22:13:56 -07:00
Detlef Riekenberg
3d128041c3 include/tccdefs: Add function renaming with __REDIRECT_NTHNL (0.9.28rc testing)
Fixes a compilation break in "glob.h"
Detected during tcc 0.9.28rc testing.
Affected project: https://github.com/craigbarnes/dte

--
Regards ... Detlef
2023-09-17 12:15:28 +02:00
Sergey Sushilin
7f39b4f573 Fix typo in atomic_compare_exchange_weak() 2023-09-09 23:28:45 +03:00
herman ten brugge
31206a5bb8 Fix tests/tests2/Makefile for win32 2023-09-07 20:19:42 +02:00
herman ten brugge
9bb9a04b5f Small fixes
The testcases 22_floating_point and 24_math_library did not work with
make tcov-test
Add -lm for these in tests/tests2/Makefile

gcc -fanalyzer complains about tcc_malloc and tcc_realloc because
malloc(0) and realloc(ptr, 0) is not tested correctly.
2023-09-07 20:05:51 +02:00
grischka
086870addd configury update & bump VERSION to 0.9.28rc
configure:
- option --targetos=... for cross build
- cleanup

win32/build-tcc.bat:
- option -b <bindir>
- make 'libtcc1.a' and cross-prefix-libtcc1.a
  (same convention as with makefile)

Makefile:
- streamline tcov-tests, help, etc.

workflow/build.xml: simplify
- using "windows-2019" runner (instead of windows-latest)
  because its msys seems more complete and has no problems
  with the 96_nodata_wanted.test either.

Changelog,TODO,USES,tcc-doc.texi: update
2023-09-06 22:42:52 +02:00
grischka
8c5fe87665 tcc -g1 : small debug info (lines/functions only) 2023-09-06 22:42:47 +02:00
grischka
452045422b win32: pe dwarf sections & option -g.pdb
On windows, create a .pdb file with option "-g.pdb"
Such executables created by tcc can be debugged with
"ollydbg" or "x64dbg"

This currently relies on the 3rd party tool cv2pdb from
    https://github.com/rainers/cv2pdb
which again relies on
    mspdbsrv.exe mspdbcore.dll msobj80.dll mspdb80.dll
from a MSVC installation.

cv2pdb.exe + the ms* files may be put in the path or in the
same directory as tcc.exe.
2023-09-06 22:42:44 +02:00
grischka
cd75ca692a stuff & fixes
libtcc.c:
- revert "Small patch to allow..." (someone's personal easteregg)
  (see da3a763e97)
- check return value from macho_load_tbd/dylib

tcc.c:
- remove help for "not yet implemented" option

tccelf.c:
- check PIE's for "unresolved symbols"

tccgen.c:
- avoid int->double->int cast
  (see a46372e910)
- fix constant propagation with pseudo long doubles
  (must mask out VT_LONG from type)
- cleanup find_field() (again)

tccpp.c:
- disallow strings and double constants in #if expressions

win32/include/uchar.h:
- change file mode
2023-09-06 22:42:30 +02:00
grischka
3f3cbb51ed bcheck: remove "tcc_location()" & x86_64 double fix
using (modified) tcc_backtrace() instead.
Also

Also fix the original bug with doubles on x86_64.
(which was not caused by incr_offset() actually).
See 598134fff6

Also cleanup on_exit() stuff
From fef701b57f
2023-09-06 22:42:21 +02:00
herman ten brugge
ff2a372a9a Add tcov support in Makefile
The following targets are added:
testc / testc2.all / testc2.37 / testc2.37+ / testc2.37-
testcpp.all / make testcpp.17
This allows to check that the testcase(s) test the code modified.
See Makefile tests/pp/Makefile tests/tests2/Makefile

lib/tcov.c: Fix while loops with fgets.

tcc.h: Fix tcc_p compilation with latest gcc

tests/tests2/22_floating_point.*: Better test floating point
2023-08-31 11:09:49 +02:00
herman ten brugge
b50a0bdf31 Add bound checking for test 132 2023-08-30 16:44:44 +02:00
herman ten brugge
598134fff6 Undo part of incr_offset patch.
The incr_offset offset code was not working with bounds checking.
So I reverted part of tccgen.c.
See new test code 132.

Also added some debugging code that prints location of
bounds checking calls. Needed this to find the problem.
See lib/bcheck.c, lib/bt-dll.c, lib/bt-exe.c, lib/bt-log.c, tccrun.c
2023-08-30 16:10:39 +02:00
noneofyourbusiness
d1c107738b
riscv64-asm.c: add jal/jalr
this implements the base instructions, not the pseudoinstructions

examples
 jal ra, 0
 jalr x0, ra, 0
2023-08-11 10:08:41 +02:00
noneofyourbusiness
e70fec871b
riscv64-tok.h: update with more instructions from the spec
defined tokens for C, M, Ziscr extensions.

separate the base RV32 instructions from the RV64, for potential future
re-use in a RV32-only assembler, from which the RV64-tok can #include

scall, sbreak have been renamed (page 7 of spec),
necessitating some renaming in riscv64-asm.c

riscv-spec-20191213.pdf was used,
in which the "V" extension is not yet ratified.
available under https://riscv.org/technical/specifications/

Tables 16.5–16.7 do not list any "scall"
neither does the privileged spec

3 additional tokens not present in the tables were removed

note that this riscv64-asm.c still contains defects, which will
be addressed in another commit
2023-08-10 14:25:03 +02:00
grischka
c29420ab0d tccgen: update "Fix invalid load generated by gfunc_return()"
tccgen.c:
- new function incr_offset(int) to increment a lvalue
- use it in gv/vstore to load/store from/to two-word types
- use it to advance the pointer to struct fields
- use it to load/store structs passed in registers
- structs: always assume that reg-classes of registers are 2^n
- adjust stack space when regsize > sizeof the_struct

x86_64-gen.c:
- return regsize=16 for VT_QLONG/QFLOAT

i386-gen.c:
- pass structs of size(8) as two VT_INT rather than one VT_LLONG
  (both should work now)

fixes a82aff3337
fixes fd6d2180c5 (slightly)
2023-07-31 12:22:15 +02:00
grischka
022fb4293b tccpp: #pragma once normalized
In order to detect a "same file" faster, this makes one
restriction to the feature: the basenames are required to
match at least (as in "test.h" and "dir/../test.h")

Also remove obsolete 'pp_once' (cached includes do not persist
across compilations anymore anyway)

This rewrites commits
30fd24abd4
4e363a1728

 3 files changed, 38 insertions(+), 74 deletions(-)
2023-07-31 12:22:10 +02:00
herman ten brugge
fd6d2180c5 Align stack when returning structs.
The stack was not aligned when a returned structure was stored on stack.
This resulted in destoying of previous values stored on stack.
See testcase 119 (tst_struct_return_align) where value d is overwritten.
2023-07-31 09:24:06 +02:00
herman ten brugge
5b28165fbf Fix test 131 for 32 bits targets 2023-07-05 19:28:58 +02:00
Yao Zi
a82aff3337
Fix invalid load generated by gfunc_return()
On backends that rely on gfunc_return() to handle structures
  returned in registers (like RISC-V), gfunc_return() may generate
  invalid loads for structures without VT_LOCAL and VT_LVAL. This
  commit fixes it and adds a regression test
  (131_return_struct_in_reg)
2023-07-02 04:02:36 +08:00
herman ten brugge
c92f4f52d9 Update pragma once for file operations
Use open/read/close instead of fopen/fread/fclose for tcc4tcl and ziptcc
2023-06-26 11:19:41 +02:00
herman ten brugge
4e363a1728 Small update on pragma once
Update on calc_file_hash. Use xor instead of +.
Only calculate has if file name differs in search_cached_include.
2023-06-26 06:33:46 +02:00
herman ten brugge
30fd24abd4 Allow different names for pragma once
pragma once can now be used with
test.h
./test.h

and other references to the same file just like gcc/clang.

On linux we can use stat and st_ino to check for the same file.
On windows the st_ino does not work so we calculate a file hash
if the size of the file differs and then compare the hash.
2023-06-25 20:23:58 +02:00
OldWorldOrdr
5077d4c915 change which to command -v 2023-06-12 03:53:05 -04:00
waltje
583c3b4746 Update to previous patch (remove the strcpy.) 2023-05-29 20:46:44 -04:00
waltje
da3a763e97 Small patch to allow for the TCC.EXE (and TCCLIB.DLL) to reside in a (directory under) a "bin/" directory at the same level where the "include/" and "lib/" directories are. This allows one to set the PATH to the (proper) binaries directory and TCC will then "find" itself there. Tested under Windows 7, Windows 8.1 (ARM) and Windows 10+11, but should also be workable for Linux and macOS. 2023-05-26 20:19:21 -04:00
herman ten brugge
a46372e910 Add support for constant float compare 2023-05-22 15:09:59 +02:00
grischka
0ec3a40dfd about CONST_WANTED & VT_NONCONST
- integrate CONST_WANTED with nocode_wanted
- expr_const() checks VT_NONCONST
2023-04-25 15:43:38 +02:00
grischka
bb93bf8cd2 stuff & etc..
- tccpp.c: rename ... to __TCC_BCHECK__/__TCC_BACKTRACE__
- libtcc.c: correct total line count
- libtcc.c: support -run -- args... (instead of -run @ args ...)
- Makefile/build-tcc.bat: streamline GITHASH string somewhat
- bt-exe.c: avoid redef of pstrcpy() with 'tcc -bt tcc.c ...'
2023-04-25 15:22:31 +02:00
grischka
a045400501 CStrings leakless
avoid memory leaks with lost CStrings on stack after errors.

tccpp.c:
- use/abuse static Cstring tokcstr where possible
tccgen.c:
- use/abuse static Cstring initstr where possible
tcc.h/libtcc.a:
- add 'stk_data' array to track memory pointer on stack
- add macros stk_push/pop() and cstr_new/free_s()
tccasm.c:
- use that
- use char[16] instead of char* for op.constraint
2023-04-25 15:22:20 +02:00
grischka
40131b7e0f MEM_DEBUG thread-safe & tccdbg leakless
libtcc.c:
- guard tcc_realloc/free_debug() with a semaphore
tccdbg.c:
- allow tcc_debug_end() to be called twice safely
2023-04-25 15:22:15 +02:00
grischka
7916cf71cc tcc_error_noabort(): always use this unless compiling
This avoids 'exit(1)' with errors outside of compilation
(nasty in particular with libtcc usage)

As a sideeffect multiple errors can be seen for linker
errors (such as undefined symbols, relocation errors, ...)
2023-04-25 15:22:03 +02:00
grischka
19ef024aa9 lib/armeabi.c: fix zero from/to double conversion
tccgen.c:
- allow cross-compiling 0.0L (cross-compile tcc with tcc)
tccelf.c:
- use alignment of TLS section for PT_TLS
tccpp.c:
- support long double constants on systems that do not support
  long doubles (i.e. mark them (VT_DOUBLE | VT_LONG))
tccdefs.h:
  #define __has_feature() for android
  remove _unaligned (why define a msvc extension under !_WIN32)
2023-04-25 08:59:42 +02:00
grischka
86f3d8e331 tccpp: remove unwanted space with __VA_ARGS__
reported by "vsfos"
https://lists.gnu.org/archive/html/tinycc-devel/2023-04/msg00007.html
2023-04-20 14:18:29 +02:00
herman ten brugge
6a24b762d3 Do not crach when compiling with libtcc. 2023-04-15 15:36:13 +02:00
herman ten brugge
24c930a9b8 Allow _unaligned and __unaligned on WIN32 2023-04-15 15:33:14 +02:00
Ziyao
b006b98334
Fix passing of large function arguments on riscv64
- Correct stack adjustment in gfunc_call()
- Add a regression test (130_large_argument)
2023-04-09 06:06:10 +08:00
Detlef Riekenberg
e7262accb6 Print correct values in tcc_print_stats (yarpgen v1)
Value 0 and values >2GB where printed wrong during tests with yarpgen (v1)
Starting the output with a hashtag make it compatible to TAP

--
Regards ... Detlef
2023-03-23 20:02:19 +01:00
Detlef Riekenberg
afa05caacf Ignore _unaligned and __unaligned. Required >15years ago, but still present in old code
These extensions where used by other compiler
to generate different code on old cpu's (arm and x86 before pentium/pentiumpro)
to prevent processor exceptions / very high delays when accessing an unaligned pointer.

--
Regards ... Detlef
2023-03-23 17:14:29 +01:00
herman ten brugge
95aab7d687 tests/tcctest.c: Add support for osx with clang 10 2023-03-18 14:02:52 +01:00
Avi Halachmi (:avih)
e21523529b configure: OSX/macos: autodetect new_macho value
Use old (=no) if autodetect succeeded and osx ver <= 10, else new.
Override is possible, and now also documented at ./configure --help.
2023-03-18 11:42:48 +02:00
Michael Matz
4dc4e93f1d Fix 128_run_atexit.c on linux
if we include standard headers on glibc-based systems then
we can't use '__attribute__' (those are defined away for unknown
compilers) but must use '__attribute' (or #undef that token).
2023-03-13 17:01:35 +01:00
grischka
19e3e10e4b small scopes cleanup etc.
tccgen.c:
- just track local_stack for small scopes (can't declare variables)
- fix a vla problem with nested scopes
- move debug N_L/RBRAC into curly braced block

Also:
- tccpp.c: move 'label_...' functions to tccgen.c
- tccpp.c: let get_tok_str() say "<no name>" for anonymous symbols
- tcctest.c: let __pa_symbol() work for memory > 2GB
- 119_random_stuff.c: revert strtoll test (no reason to test libc)
- tccdefs.h/tcctest.c: enable bit fncs for _WIN32
- Makefile:
  - use i686-linux-gnu instead of i386-linux-gnu for cross-i386
  - update 'make help'
  - revert umplicit 'make all' with 'make install' (but print warning)
2023-03-12 20:40:50 +01:00
grischka
5f08561e10 Revert ""Fix" nocode_wanted in expr_landor"
instead in vcheck_cmp(), pass the CODE_OFF_BIT to generators
unless other nocode purposes are set.

This reverts commit cad8739594.

Also in 128_run_atexit.c:
avoid line output disorder which may happen on windows when
tcc itself and runned code are using two different printf
implementations and tcc would print the "[Returns 1]" above
any output from the runned test.
2023-03-12 13:39:07 +01:00
Detlef Riekenberg
7abf2c03d6 fix: Do not define INCLUDE_STACK_SIZE twice
We have that define already in tcc.h
and changing the define in tcc.h breaks compilation of tcc
without this fix.

--
Regards ... Detlef
2023-03-11 14:13:23 +01:00
herman ten brugge
cad8739594 Fix nocode_wanted in expr_landor
The generated code by yarpgen failed. I traced the problem to
expr_landor. The problem was that nocode_wanted was removing
too much code.
See also testcase 33.
2023-03-11 07:51:00 +01:00
herman ten brugge
cb3589c56e Increase VSTACK_SIZE to 512.
The yarpgen test code uses very complex expressions.
2023-03-11 07:40:56 +01:00
herman ten brugge
88d5c70bdb Update casted boolean expressions
The problem was that enums can also be present in vset_VT_JMP.
Also see testcode.
2023-03-11 07:35:42 +01:00
Michael Matz
ef3eb02ccb Fix type of cond-op
the optimization of a ternary op with two boolean operands had
the same problem (as in the last commit) of loosing the type.
2023-03-10 17:23:55 +01:00
Michael Matz
96b31ba670 Fix casted boolean expressions
the casted type was lost when a delayed bool was finally converted
to a value.  See testcase, in the wrong case the '(unsigned int)' cast
was ignored, and hence the division was signed reulting in -1 instead of
the proper 0x7fffffff.
2023-03-10 16:49:27 +01:00
herman ten brugge
2cb8bddd82 Add attribute nodebug support and skip bitfield padding
The following code:
typedef struct {
  unsigned int a __attribute__((nodebug));
  unsigned int b;
  unsigned int : 32;
  unsigned int c;
} tst;

Supresses a and also suppresses bitfield padding.
So debugger shows only b and c in above example.
2023-03-10 12:41:43 +01:00
Michael Matz
2cf3a6eb4d Fix more jumpopts (in ternary op)
the code in expr_cond save nocode_wanted around some parts of
expression evaluation, but at the wrong spots.  If the evaluation
of the condition itself (e.g. in the testcase the first whole ternary
expression) resulted in CODE_OFF, then that was saved, and restored
before return, even if in-between codegen would have CODE_ON'ed already.
Thus the whole CODE_OFF state bled out to outside the expression
evaluation and also disabled the whole if-block.  Found by yarpgen v1
(seed 64).
2023-03-09 18:23:16 +01:00
herman ten brugge
ec81877fa7 Fix test90 for 32 bits targets
Should have used 'long long' instead of 'long' for 32 bits targets.
2023-03-09 16:11:39 +01:00
herman ten brugge
80909254c4 Fix Makefile install target
Update target all before installing
2023-03-09 16:00:46 +01:00
herman ten brugge
3f0a1719dc Fix init bitfield padding with size 32/64
The init code did not work for padding bitfields with size 32 and 64.
2023-03-09 15:53:48 +01:00
Michael Matz
c771cb52fa Fix code suppression during nocode_wanted
we activate code (CODE_ON) only when the target labels are used,
which doesn't happen during nocode_wanted regions.  So, we cannot
just switch off code either during nocode_wanted regions, nothing
would switch it on again (except in the happy coincidences when we
outright save/restore nocode_wanted).  See the testcase for one
example, reduced from code generated by yarpgen: in
  ext = (xxx || 1)           // #1
        || ((xxx && 1) || 1) // #2
code is first suppressed in #1 normally, then (before this commit)
was suppressed via CODE_OFF during #2 (via indirect gjmp),
then the suppression from #1 was undone, but nothing undoes the
suppression from #2 anymore as everything therein was generated
while nocode_wanted was active.

So, we would either need to save/restore nocode_wanted around
some more expressions, activate CODE_ON also with unused labels (breaks
some optimizations we want), or deactivate CODE_OFF only when not
already in nocode_wanted state.  This does the latter.
2023-03-07 18:10:02 +01:00
Petr Skocik
ccc1651075 Create scopes for switches/whiles/do-whiles
The C standard has required this since at least C99.
A new scope should also be created for ifs, but that's currently
breaking tests2/122_vla_reuse.
2023-03-05 22:31:40 +01:00
Brian Callahan
29ae3ed4d5 OpenBSD has removed the syscall() function from its libc, so we
need to use getthrid() directly in lib/bcheck.c
2023-02-23 17:19:37 -05:00
Michael Matz
605538f46d Fix sym_scope of typedefs
Sym.sym_scope and Sym.f (FuncAttr) share space, so blindly setting
one clobbers the other.  Right now this only leads to missing errors
on incompatible typedefs (see testcase), which this commit fixes.

But it points to a larger problem:
Generally we can only manipulate Sym.f for anonymous and field symbols,
not for anything that has a top-level name (basically any proper decl),
because the latter use sym_scope.  Luckily the functions type always
contains an anonymous symbol (in sym->type.ref), so we can use that.
But some of the functions attributes actually _do_ apply to the decl,
not the type (e.g. always_inline), so we still have a problem possibly,
when we update an pre-existing type that may already be shared with
another decl.

Would need untangling and perhaps using accessor functions that check
that Sym.f and Sym.sym_scope aren't used for the same symbol.
2023-02-22 17:59:31 +01:00
Detlef Riekenberg
bdec3c5345 Use unsigned int to count sizes for -bench (YARPgen) (part 2)
I have a testfile created by YARPGen (seed=9), which displayed
a negative bss size without this patch.

* tcc needs also a bigger VSTACK_SIZE (i used 512)

--
bye bye ... Detlef
2023-02-03 18:04:56 +01:00
Detlef Riekenberg
b2485d6cd5 Use unsigned int to count sizes for -bench (YARPgen)
I have a testfile created by YARPGen (seed=9), which displayed
a negative bss size without this patch.

* tcc needs also a bigger VSTACK_SIZE (i used 512)

--
bye bye ... Detlef
2023-02-03 01:04:38 +01:00
herman ten brugge
4dc7662a07 Fix preprocessor line directive update
The last commit was not a problem with macos.
The problem was that dwarf version < 5 uses different indexes for
files and directories.
They start at 1 for dwarf version < 5 and 0 for dwarf version >= 5.
2023-01-17 20:08:14 +01:00
Christian Jullien
7874397373 Don't forget to mention the amazing job made by Herman on native macOS. 2023-01-17 15:29:57 +01:00
noneofyourbusiness
4cccba74d2
update changelog 2023-01-17 13:38:04 +01:00
herman ten brugge
d0efbc5d3a Fix preprocessor line directive for macos
Macos has an offset of 1 for DW_LNS_set_file.

Also rewrite dwarf_file to not scan list twice and
move check for <command line> to this function.
2023-01-16 20:26:44 +01:00
herman ten brugge
ee3fef2ce2 Fix preprocessor line directive
The preprocessor line directive did not result in correct debug info
when -g was used.
Line directives like:
 #line 1 "filename"
should now work.
2023-01-16 08:39:34 +01:00
herman ten brugge
79d439ee4f Allow const expr in builtin_frame_address/builtin_return_address 2023-01-16 08:37:47 +01:00
noneofyourbusiness
560526a49d
Changelog: get started with the changelog since 0.9.27 2023-01-01 16:39:14 +01:00
noneofyourbusiness
fa0fa62b0c
Makefile: remove unportable -v flag from distclean target 2023-01-01 16:30:57 +01:00
herman ten brugge
20a22cf3d6 Fix tcc -ar c symbol header size
tcc -ar t failed sometimes because the header size was not correct.
2022-12-28 07:38:39 +01:00
noneofyourbusiness
d15dec711d
tcc -ar: change mode to 644, use ARMAG 2022-12-28 03:08:02 +01:00
Per Nordlöw
9957c686a4 Remove _Static_assert verifying the size of CString because it breaks C99 builds with gcc-5 2022-12-28 00:31:14 +01:00
Per Nordlöw
78c3ea30a6 Reduce CString memory usage from 3 to two 2 words 2022-12-27 21:50:39 +01:00
herman ten brugge
7ed9c95ae7 Allow parallel build testsuite 2022-12-27 14:11:18 +01:00
herman ten brugge
d1fa89a11f Fix problem with large section size.
In tcc_load_object_file use unsigned long for size/offset.
This avoids strange sizes of sections in case of overflow.
The sections that are now larger then 4G may not work.
This avoids a hang on macos in realloc.
2022-12-27 07:45:38 +01:00
noneofyourbusiness
676755f6ee
help: also update main help with tcc -ar options and sort them 2022-12-26 01:48:54 +01:00
Christian Jullien
95e39517ef Add -Wl,-install_name macOS clang compatible flag as clang refuses -Wl,-soname. This helps configure scripts using both clang and tcc. 2022-12-24 09:30:00 +01:00
herman ten brugge
3fd6a05fff Fix multiple rpath tccmacho
If multiple rpaths are specified then output multiple LC_RPATH load
commands instead of one with : seperator.
2022-12-23 19:48:39 +01:00
herman ten brugge
03841b6f16 Update bind problem macho
Changed -1 into -2 for plt_offset,
2022-12-23 12:17:55 +01:00
herman ten brugge
da0cc61794 Fix bind problem macho
The problem occurs when a shared library creates a pointer to
a function and then the application also uses this function.
2022-12-22 20:50:37 +01:00
grischka
62d857a6f9 tccgen: better find_field() not found error messages
Also: return all of 'cumofs' (no extra '+' required at caller)
2022-12-22 16:17:39 +01:00
herman ten brugge
909d58dd5e Add tcc -ar x and t options
On macos we cannot use the ar because is does not support elf files
and then does not generate a symbol table.
The solution is to use 'tcc -ar'. The problem now is that some
pacages first built an archive with 'tcc -ar c' and later extracts
the archive with 'tcc -ar x' and built with this a dylib file.
The 'tcc -ar x' failed. So I implemented it. I also added the t
option because it was simple to do,
2022-12-20 07:34:41 +01:00
herman ten brugge
d5f25d19b3 Add macos clang/ld compiler options
With these option I can now built several packages without problem.
There are a lot of options we can add so I tried to implement the
minumum.

Add the following options:
dynamiclib		same as -shared
flat_namespace		default/ignored
two_levelnamespace	ignored
undefined		default/ignored
install_name		name of dynmic lib
compatibility_version	version dynamic lib
current_version	version version dynamic lib

-Wl options:
all_load		same as whole-archive
force_load		same as whole-archive with lib
single_module		ignored
2022-12-20 07:24:48 +01:00
herman ten brugge
f6f3d646fb Fix dll support for macho
Export now all global symbols in export trie instead of only text
symbols.

I wrote too much data into dylib file because I did not check
for sk_unknown/sk_discard/sk_uw_info.

Simplified code in tccrun.c
2022-12-18 14:07:19 +01:00
herman ten brugge
04810db83a Allow building lib with gcc/clang
Needed when using ...libtcc1-usegcc=yes in lib/Makefile.

lib/bcheck.c: Add __clang__ for pragma diagnostic
lib/bt-log.c: Add pragma diagnostic as in lib/bcheck.c
lib/builtin.c: Add a lot of alias code to allow building with gcc/clang
lib/stdatomic.c: Same as lib/builtin.c
lib/tcov.c: Avoid clang compiler warning
2022-12-17 09:37:37 +01:00
herman ten brugge
d66a62fa6b Fix dll support macho for x86_64
Macho uses bind/rebase instead of dynsym so disable them for relocate_sections.
2022-12-17 07:43:01 +01:00
herman ten brugge
8d3930bdb6 Add dll support for macho
Update configure and remove dll=no for Darwin.
Also removed dwarf=$dwarf because this is not a config option.

In tccelf.c only add __PAGEZERO if stabs and executable.

In tccrun.c correct rt_printline_dwarf code for dll.

In tests/Makefile disable dlltest with PIC for Darwin because object
format of .o file is still in elf.

In tccmacho.c add dll support and and rpath support.
Corrected trie code. For some reason symbol 'xx' should be after 'xx1'.
Corrected weak symbol support for old macho code.
Used R_JMP_SLOT instead of R_DATA_PTR in check_relocs.
2022-12-16 20:57:45 +01:00
Mathias Krause
9cfc8f60ce x86asm: Add lzcnt/tzcnt support
We already support popcnt, add lzcnt and tzcnt as well.

Signed-off-by: Mathias Krause <minipli@grsecurity.net>
2022-12-13 11:34:54 +01:00
herman ten brugge
079692016d Fix stab debug problem with common section 2022-12-11 15:36:37 +01:00
herman ten brugge
dd69143ae6 Add builtins ffs, clz, ctz, clrsb, popcount, parity
Add new file lib/builtin.c
Modify include/tccdefs.h, lib/Makefile to compile it.
Update tests/tcctest.c to test it.
2022-12-11 08:23:22 +01:00
Petr Skocik
ea0c57e90a Allow _Static_assert declarations in structs
This usage has been part of the C grammar since C11
(http://port70.net/~nsz/c/c11/n1570.html#6.7.2.1) and is
also supported by gcc and clang.
2022-12-10 01:12:44 +01:00
herman ten brugge
ac9eeea1d5 Enable vla_test-run on all targets
Fix gen_vla_sp_save/gen_vla_sp_restore in riscv64-gen.c
2022-12-06 11:21:50 +01:00
herman ten brugge
657262c7e5 Enable testcases on apple and x86_64 2022-12-06 08:09:16 +01:00
Christian Jullien
d0c26ba4e5 OSX is used and can't be replaced by macOS yet, revert previous change 2022-12-05 16:28:54 +01:00
Christian Jullien
d1f5d132c6 cosmetic: OSX is a deprecated name, macOS is the official system name for Apple Operating System since 2016. 2022-12-05 15:42:38 +01:00
Christian Jullien
a0f88dca75 on macOS, configure displays the dwarf version used, currently dwarf=4 2022-12-05 15:22:46 +01:00
herman ten brugge
6b9c0024ac Default is now config-new_macho and dwarf=4 for apple
I tested on macos 10, 11, 12 and 13 that old and new macho code work.
I do not know when this new format is introduced but it is now
available on a lot of versions. So make it the default.

Also default to dwarf=4 because stabs and dwarf=5 is not supported.
2022-12-05 11:10:03 +01:00
herman ten brugge
85b27432bb Fix libtcc_test_mt
The test failed because atexit/on_exit code was not correct.
Make it look more like the g_exit_context.
Added a sleep to libtcc_test_mt to allow overlap of threads to
detect this problem.
2022-12-04 11:55:06 +01:00
herman ten brugge
e2db3a5e57 Update load segment code for macho
Add an array with segement to load instead of code.
Dynamically check if segment is used or not.
This fixes the strange __DWARF code segment handling.
2022-12-04 07:27:10 +01:00
herman ten brugge
7cc1cc3881 Fix for lldb usage
lldb does not like function end and next function start at same pc
2022-12-04 07:19:48 +01:00
noneofyourbusiness
ab39d34dde
produce a more informative error message when _Thread_local is used 2022-12-03 20:09:11 +01:00
herman ten brugge
894e166ecf Better fix for old macho format
The last commit only worked on arm64.

The problem was that the new __DWARF segment was empty.
I now remove the __DWARF segment if it is not needed.
This resolves the rebase problem on x86_64.
2022-12-02 22:57:49 +01:00
herman ten brugge
14e78d7cc2 Old macho format does not work with previous push 2022-12-02 20:25:27 +01:00
herman ten brugge
b7356bb638 Reduce memory size macho executables
Do not align vmsize/filesize to SEG_PAGE_SIZE every time.
Move rel_offset check down due to this change.
2022-12-02 13:53:37 +01:00
herman ten brugge
6b398686d6 Fix bounds checking without -run on macos
Update tccrun.c to detect rebase for dwarf debug info.
Enabled testcase 126 on macos.
Add prologue_end/epilogue_begin supoort in tcc.h, tccdbg.c, tccgen.c.
2022-12-02 13:09:47 +01:00
Christian Jullien
ffbf6c26b2 Test was inverted for locally modified version 2022-12-02 08:40:12 +01:00
Christian Jullien
bdaccc2898 Minor -v improvement: remove extra space 2022-12-02 08:28:14 +01:00
Christian Jullien
7015838f51 Use my latest proposed patch for improved -v message. It is simpler and gives a better message, especially when repository has been locally modified: 'tcc version 0.9.27 mob:fef701b 2022-12-02T07:11:55+01:00 locally modified (ARM eabihf Linux)'. Hope it's Ok for maintainers 2022-12-02 08:05:01 +01:00
herman ten brugge
fef701b57f Allow on_exit to be used with -run
Added on_exit support for tcc -run.
Also fixed the last atexit code.
Updated testcase 128
Fixed test/test2/Mafile for testcase 126
2022-12-02 07:11:55 +01:00
herman ten brugge
60d52f0d68 Fix add debug support to macos 2022-12-02 07:05:12 +01:00
noneofyourbusiness
702b802316
TODO: add releases - it's been a while since the last release 2022-12-01 10:03:56 +01:00
noneofyourbusiness
4cb99787a7
make tcc -v more informative (also add commit date/time)
patch from 'Christian Jullien' <eligis@orange.fr>
2022-12-01 06:33:51 +01:00
herman ten brugge
62096265ed Add debug support to macos
lldb now works with this push.

In tccmacho.c add S_ATTR_DEBUG to all debug sections.
Add __DWARF section and rearange struct skinfo.

In tccdbg.c The first filename in dwarf_line can not be used.
Also had to fix structure/union/lexical_block/subroutine to
allow empty childs.
dwarfdump --verify complained about this.
2022-11-30 21:49:07 +01:00
herman ten brugge
ac0604a4d4 Allow atexit to be used with -run
Add atexit code to tccrun.c and added testcase 128
2022-11-29 21:13:20 +01:00
herman ten brugge
065b401c6e Fix static assert with empty string 2022-11-29 19:45:05 +01:00
herman ten brugge
a722a124f3 Allow %n in *printf functions on macos
The problem is that %n in *printf functions require a format string
that is in a read only section. See man page.

So added __DATA_CONST segment and mapped rodata_section into this segment.
Also added __got to this segment.

Change maxprot of segments to the same values used by clang.
2022-11-29 11:15:21 -06:00
herman ten brugge
afcdaf121a Fix __builtin_constant_p with comma expression
See: https://savannah.nongnu.org/bugs/?58606
and: mpfr-4.1.1/tests/tcmp_ui.c

The code '__builtin_constant_p ((i++, 7))' was not working.
I Fixed it in tccgen.c

I added a testcase in tests/tcctest.c. I also wanted to add a test like
'__builtin_constant_p ((10, 7))' but gcc needs -O1 for that to work.
clang (and now tcc) work as expected.
2022-11-29 00:56:26 -06:00
herman ten brugge
747ad409ac New update tccmacho.c
Fix for external functions as pointers in data section.
See testcase 119 and tccmacho.c in check_relocs.

Make bind/rebase code faster in bind_rebase_import.
- Move reloc check out of loop
- Because relocs are sorted we can do bind/rebase by page.

Change name head into seq in trie code.

Remove unused code in bind_rebase.
2022-11-28 11:19:33 -06:00
herman ten brugge
6b9fb93cd1 Fixed trie code generation for apple
I removed the FIXME for generating trie code with working code.

I also fixed a problem where:
cc -g -c a.c; cc -o a a.o
created a bind/rebase error because the second cc did not use -g
and .debug sections where not checked correctly.

I also removed the elfinterp printout in tcc.c when
TCC_TARGET_MACHO is set.
2022-11-27 07:28:40 -06:00
Christian Jullien
d8329c2d19 __nan() is not available on Apple M1, replaced by (0.0F/0.0F) 2022-11-25 17:08:58 +01:00
grischka
312d28b0a8 tccelf: avoid find_section() for known section
- remove calls to "find_..." for stuff that we know to exist and where.
- rename find_section_create(s1,name,0) -> have_section(s1,name)

Also:
- call update_gnu_hash() from elf_output_file()

gnu_hasn() functions could be moved down into an already existing
!ELF_OBJ_ONLY clause, but in order to avoid too many diff lines
I didn't.

- avoid 'long' (elf_hash). sizeof (long) is host-dependent (4 or 8)
- remove unnecessary checks (for dynsym, versym).

Someone reading "if (dynsym == NULL) ..." must conclude that it
actually can happen under certain circumstances, or otherwise,
might conclude that the person who wrote that felt unsure what's
going on exactly.

arm64-gen.c:
 TCC_TARGET_MACHO instead of __APPLE__ (to support cross-compilers
 for the apple/M1 target)
2022-11-25 12:13:47 +01:00
herman ten brugge
28fa4d3db6 Add strncat and strrchr to bounds checking 2022-11-25 00:31:32 -06:00
herman ten brugge
f48efeef8c Update to run on apple 13.0 (Ventura)
Add --config-codesign option to run codesign on apple to sign executables.
See configure and Makefile

In tccmacho.c use codesign option to call codesign application.
Add build_version/source_version
Sort sections in __LINKEDIT the same way as llvm does.
Add simple support for trie code. Need some more attention.
Fix rebase/bind error.
2022-11-25 00:19:45 -06:00
herman ten brugge
b86d82c8b3 Add new macho object format to tccmacho
Apple has a new object format that uses chained fixups.
I have implemented this with a configure option '--config-new_macho'
See configure and Makefile

tccmacho.c contains the biggest change.
I split the lazy_bind_rebase structure into lazy_bind and rebase for the
old format.
Under the macro CONFIG_NEW_MACHO there is the new macho format code.

In arm64-gen.c we do not need to push all registers on stack for
variadic functions. variadic parameters are pushed on stack for apple.

There is still one open isue. The export trie is empty.
This only effects dlsym when a local symbol is used.

tested on apple x86_64(10.5) and arm64(12.3).
2022-11-22 23:58:40 -06:00
herman ten brugge
d605d75ba8 Fix stab support for apple 2022-11-18 01:56:46 -06:00
herman ten brugge
d578151f8c Fix weak support apple 2022-11-18 01:51:36 -06:00
herman ten brugge
e99cf72784 Add weak support apple
Update tccmacho.c for weak symbols.
Undo tests/tcctest.c disable weak symbols test.
2022-11-17 14:03:00 -06:00
Christian Jullien
233d5d5f6f Fix old_style_f call when compiled by clang. 2022-11-17 14:35:31 +01:00
herman ten brugge
f89a6f12a7 Fix atomic test_and_set and clear
The __atomic_test_and_set and __atomic_clear code was correct.
They needed locking.
Replaced to code with assembly code.
The changes are in include/stdatomic.h, lib/stdatomic.c, lib/atomic.S
Enabled tests/tests2/124_atomic_counter.c for apple again.

Also moved lib/fetch_and_add.S code to lib/atomic.S.
Removed lib/fetch_and_add.S
Adjusted lib/Makefile
2022-11-17 05:57:21 -06:00
herman ten brugge
c8ef84c854 Add support for apple m1
The apple m1 uses position independent executables (pie).
I have implemented this in tccmacho.c

Apple also uses the stack different for var_args.
Also characters are signed instead of unsigned.
This is implemented in arm64-gen.c/tccdefs.h

Add bounds checking lib to lib/Makefile.

Add underscore support in lib/atomic.S and lib/fetch_and_add.S

Disable __clear_cache in lib/lib-arm64.c (Use system version).
I will try to fix this in future push.

Disable test_asm_call in tests/tcctest.c. Clang does not support @plt.
Also disable weak symbols test.
I will try to fix weak support in future push.

Disable tests/tests2/124_atomic_counter.c for 64BITS.
This is a bug in the atomic code and will be fixed in future push.

You have to use --dwarf configure option. stabs only works with -run.

tested on apple x86_64(10.5) and arm64(12.3).
2022-11-16 12:52:51 -06:00
Vlad Vissoultchev
c6b722f3f8
github: use macOS 11.7 and silence 96_nodata_wanted on Windows 2022-11-12 15:21:17 +02:00
Christian Jullien
8eabf67e1e Fix typo in tst_strtoll_strtoull. The wrong function was called for unsigned long long type. 2022-11-12 06:55:39 +01:00
Christian Jullien
6219b2de00 Add tests on Windows for strtoll and strtoull. Tests can probably be used on all systems. 2022-11-11 07:12:49 +01:00
Christian Jullien
40f01478d8 Add support for missing strtoll and strtoull on Windows 32/64 2022-11-11 06:23:26 +01:00
noneofyourbusiness
aea2b53123
update TODO: static linking sort of works 2022-10-30 13:05:26 +01:00
Bernhard Reutner-Fischer
df6fd04aaf github: commentary typo fix
and remove a trailing space

Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
2022-10-23 08:52:06 +02:00
noneofyourbusiness
7d76420857
produce a more informative error message when parsing _Complex 2022-10-19 14:06:04 +02:00
herman ten brugge
878fcccdb2 Small preprocessor fix
Set BOL flag for code like:
  #define tcc_test()
  #if 1
  tcc_test
  #endif
2022-10-17 07:49:47 +02:00
herman ten brugge
79a8229fb5 Add atomic functions for arm/arm64/riscv
Make code more compatible with gcc. Change
__atomic_store
__atomic_load
__atomic_exchange
__atomic_compare_exchange

Also add (include/stdatomic.h, lib/stdatomic.c):
atomic_thread_fence
atomic_signal_fence
atomic_is_lock_free

And gcc extensions (tcctok.h, tccgen.c, lib/stdatomic.c):
__atomic_fetch_nand
__atomic_and_fetch
__atomic_sub_fetch
__atomic_or_fetch
__atomic_xor_fetch
__atomic_and_fetch
__atomic_nand_fetch

Add new file lib/atomic.S with assembly code for __atomic_compare_exchange_n
for arm/arm64/riscv. Also update lib/Makefile.

Update testcode in 124_atomic_counter and 125_atomic_misc to test new functions.
Also update tests/tests2/Makefile to run tests on arm/arm64/riscv.
2022-10-16 18:51:56 +02:00
grischka
bb80cbe0d9 tcctest.c: sizeof (long) != 8
Bad assumption make bad things happen:

    long d3;
    asm(..."1:\tdec %3\n\t" : ... "=&c" (d3)

Which wants 'dec RDI' but did 'dec EDI' on _WIN64.

Also:
- tcctest.c: enable more asm tests for win64
- configure: show errors if any with 'gcc conftest.c'
- tccgen.c: remove decl0(x, y, z)
2022-10-14 21:56:16 +02:00
mingodad
c60f1d953c Update tests on Ubuntu from 18.04 to 20.04 because github is deprecating 18.04 2022-10-14 15:01:54 +02:00
mingodad
d27ca0e0c0 Add a github action to build/test tinycc on github mirror 2022-10-14 12:31:26 +02:00
grischka
d76e03232b win64: hi-mem adjustments
- x86_64-link.c:
  ignore relocation overflow to undefined (weak) symbols
- 104_inline.test:
  test lower 32 bits only
- tccpe.c:
  support -Wl,--image-base=... above the 32bit range
2022-10-13 20:32:47 +02:00
herman ten brugge
c03d59eae0 Fix macos warning for create_gnu_hash
Also add new function modify_reloctions_old_to_new for common code in
sort_syms and update_gnu_hash.
2022-10-12 07:24:34 +02:00
Detlef Riekenberg
b9aeb21f3f gcctestsuite: Make the script usable on more systems, skip some tests
The script was expecting gcc-3.2 in a specific directory,
works only, when building tcc in the source directory
and creates >3200 files in /tmp (probably a SSD).

Now gcctestsuite.sh works much better.
* use TESTSUITE_PATH, to tell the script the location, where the actual
  gcc.c-torture directory is
* work also, when tcc was build in a separate build directory.
  use TCC_SOURCE_PATH, when guessing the tcc source directory does not work
* use RUNTIME_DIR to redirect compiler output
  (default: XDG_RUNTIME_DIR, then /tmp)
* skip tests for features not implemented in tcc ( *_builtin_*, _Complex )

--
Regards, Detlef
2022-10-12 00:59:02 +02:00
grischka
aef64762c1 tccpp: #define max(a,b) && max /= 8;
This fixes 20a1ebf854
where the '/' above was lost when max() was defined

Also: ignore binary files with -E (for example 'tcc -lxxx -E ...')
2022-10-09 20:30:15 +02:00
herman ten brugge
0fd7376000 Add .gnu_hash support
Almost all systems use .gnu_hash so implement it for tcc.
For most of them it is the default.

tccelf.c:
- Add functions elf_gnu_hash/create_gnu_hash/update_gnu_hash
- Update new_section/sort_sections/fill_dynamic/tcc_output_elf/elf_output_file

Tested with setting .hash section to SHF_PRIVATE in elf_output_file.
2022-10-06 10:07:02 +02:00
grischka
e5eedc0cda Revert "tcc.h: Extend search path for include, lib and crt"
This reverts commit 2507c71704.

Why crowd up search-paths for the normal native compiler with
all sort of invalid stuff.  Why -UCONFIG_TRIPLET if it isn't
set at all for cross-compilers.  Also, the patch still didn't
do anything useful "out of the box".

Instead I'd suggest to do something more simple and more effective.
See Makefile:
- set search paths for cross-compilers to /usr/<triplet> by default
- Install any built "xxx-tcc" and "xxx-libtcc1.a", even if not listed
  with PROGS_CROSS/LIBTCC1_CROSS
- Support ELF-<target> = ... to set the elf interpreter

Some common gnu-triplets are supported by default
  TRIPLET-i386 ?= i386-linux-gnu
  TRIPLET-x86_64 ?= x86_64-linux-gnu
  TRIPLET-arm ?= arm-linux-gnueabihf
  TRIPLET-arm64 ?= aarch64-linux-gnu
  TRIPLET-riscv64 ?= riscv64-linux-gnu

Other triplets can be given explicitly, for example like this:
  $ make cross-arm-eabi TRIPLET-arm-eabi=arm-linux-gnueabi
  $ sudo make install
2022-09-24 10:09:12 +02:00
grischka
e41730f11a - tcc -vv: show cross-libtcc1.a correctly (and more)
(As long as it is in the default install location and was not
moved elsewhere into the library search path manually)

Also:
- libtcc.c:
  - error1(): show correct line with "In file included from ..."
  - support "tcc -Bxxx -vv"
  - tcc_new()/tcc_compile(): Don't create elf sections for tcc -E
- tccdbg.c:
  - tcc -E -g : revert 1de025c13a
    Let's keep things simple, everybody understands 'do_debug'
    and dState is set by tcov too (but no debug sections).
- tccgen.c:
  - avoid the extra parameter for gind()
    (from c3e3a07ed4)
  - vla func params: use skip_or_save_block() and enable
    VT_LVAL (see 313855c232)
  - cleanup nocode_wanted a bit
- tccelf.c:
  - tccelf_end_file(): don't try to translate zero-sym relocs
    (seems to happen with asm "jmp 0x1000")
  - version_add(): do not make "ld-linux.so" DT_NEEDED
2022-09-24 09:46:17 +02:00
Detlef Riekenberg
414c22c67b configure: Fix Android detection 2022-09-24 02:33:46 +02:00
Detlef Riekenberg
2507c71704 tcc.h: Extend search path for include, lib and crt
This allow the tcc cross compilers to work as expected,
when tcc was build with '--enable-cross' and a simple config-extra.mak
(see the provided config-extra.mak.example).
Make sure, that cross development packages for libc are installed

Fixes also open bugs in various bug tracker. Example in debian: 940469
  tcc: error: library 'c' not found
  tcc: error: file 'crtn.o' not found
  tcc: error: undefined symbol 'printf'
2022-09-24 01:05:02 +02:00
Michael Matz
fa25630ce4 vla: Fix check for vla used by autoconf
1) recursive types have no storage anymore, so a
     static int (*p)[x];
   declaration is just fine
2) since somewhen VT_VLA doesn't imply VT_ARRAY anymore, so we
   now need to check VLA in at least one place before checking
   test_lvalue.

((2) should probably be cleaned up again so that VLA does again imply
ARRAY)
2022-09-19 15:32:07 +02:00
herman ten brugge
76b88e22a4 Fix last __has_include update
After this last change the radare2 project did not compile anymore.

Start with BOL flag after include ends in tccpp.c.
Update testcase 18.
2022-09-12 11:37:47 +02:00
Niklas Rosencrantz
4410dbdd7f Use uname -s since uname -o is not compatible with macOS/Darwin 2022-09-02 05:12:44 +02:00
Detlef Riekenberg
c51236eee7 libtcc: Activate DWARF debug infos with tcc -gdwarf ...
This fixes the bug that "tcc -gdwarf ..."
still creates the stab debug infos,
when tcc was build without using DWARF debug infos by default
(configure option: --dwarf=x)

--
Regards ... Detlef
2022-09-01 15:55:56 +02:00
Brian Callahan
2acf65f7e6 Fix OpenBSD PIE binary linking 2022-08-21 12:48:06 -04:00
grischka
20a1ebf854 tccpp : get rid of 'ch'
- also simplify parse(_line)_comment() and parse_pp_string()
- fixes a continuation problem in strings (see tcctest.c)
- no differences in performance could be observed

161 insertions(+), 246 deletions(-), less 85 lines
2022-08-18 11:34:36 +02:00
grischka
85c32ddd0b tccpp: integrate __has_include() more nicely
- make only one function from previously four pieces
- use parse_pp_string() for the normal cases "..." and <...>
- use the sanity check for computed include as end-condition too.
- use 's1' instead of 'tcc_state' when possible

117 insertions(+), 165 deletions(-), less 48 lines
2022-08-18 10:23:13 +02:00
herman ten brugge
0f72db09ab Add testcase __has_include and __has_include_next 2022-08-16 20:53:57 +02:00
herman ten brugge
90b68cbd58 Fix arm64 compilation
arm64-gen.c:
- Remove VT_NONCONST in load

tests/tests2/Makefile:
- Fix typo test 127
2022-08-16 17:54:42 +02:00
Michael Matz
aa9093a144 Fix null pointer constants
an expression like 'i*0', even though it's value is constant and
can be evaluated at compile time is not an integer constant expression,
and hence no null pointer constant, and therefore the conditional
operator doesn't select the other type.
2022-08-16 16:58:00 +02:00
Michael Matz
c3e3a07ed4 dce: Don't force unreachable case label to be live
if a switch is unreachable then so are the case labels.
Unlike normal labels they can't possibly be reached from not-yet
parsed code, so there's no reason to enable codegen again for those.
2022-08-16 15:59:41 +02:00
Michael Matz
0c36b3ff2d x86asm: Add movnti
in the unsuffixed form we also accept REG8 and REG16, for easier
parsing (we have no instruction type for only the LQ forms).
2022-08-16 15:59:41 +02:00
Michael Matz
64f4b00d34 tccpp: Fix #ifdef in macro args
see testcase.  We have to "empty" the macro-stack string on
end_macro, as it may be 'tokstr_buf' which is going to be used
twice in recursive invocations of macro_subst_tok.  The uses aren't
overlapping but the first one needs to be properly finalized.
2022-08-16 15:59:41 +02:00
Michael Matz
1da92cdd93 Accept attributes after labels
newer GCC can associate attributes with statements and labels,
this implements only the latter (and ignores the attributes).
2022-08-16 15:59:41 +02:00
Michael Matz
b077bc8ff7 x86asm: Add vm* and iret[wlq] insns
The no-operand vm* instructions can be interpreted as having a
funny modrm byte, but unlike no-operand OPC_MODRM it's also the
r/m field which selects the insn, not (only) the reg field (aka group),
so we need another insn type.
2022-08-16 15:59:41 +02:00
Michael Matz
2309517066 x86asm: Add popcnt
as this is the first opcode TCC supports that has a 0xf3 prefix
and uses integer registers (not SSE ones) this also needs some shuffling
of the prefix code to not generate invalid instructions (the REX prefix
_must_ come directly before the main opcode (including 0f prefix), and
hence needs to come after the 0xf3 prefix).  Also disable some mnemonics
in asmtest.S that new GAS doesn't support anymore.  The only difference
to GAS (in asmtest.S) is now the 'lock negl' instruction which TCC
emits as 'lock; negl'.  That's fine.
2022-08-16 15:59:41 +02:00
Michael Matz
98bab41cba Support asm goto
this adds generic support for asm goto, but I've tested only
on x86.
2022-08-16 15:59:41 +02:00
Michael Matz
154c3e7450 Fix unnamed bitfield struct members
they look similar to labels 'foobar : 32' (when foobar is a typedef),
but cannot be handled as such in parse_btype, the context is important
(labels can only happen when called from within 'block', aka decl0 in
VT_LOCAL context).  This got broken back in 2019 (1b57560).
2022-08-16 15:59:41 +02:00
herman ten brugge
47dc6e6d7b Add __has_include and __has_include_next support
tcctok.h:
- Add __has_include_next

tccpp.c:
- New functions parse_include and get_include_file
- Changed expr_preprocess and preprocess
2022-08-14 12:17:31 +02:00
herman ten brugge
1de025c13a Check dState instead of do_debug in tccdbg.c
This fixes:
  tcc -g -E

and programs like:
  #pragma comment (option,"-g")
  int main(void) {return 0;}
2022-08-11 09:03:13 +02:00
herman ten brugge
b7733aeef1 Fix wchar_t strings with 'x', 'u' and 'U' 2022-08-11 08:37:00 +02:00
Detlef Riekenberg
8b906427e3 tccgen: cleanup _Alignas implementation
Remove the unneeded compare, introduced in the recent _Alignas update.
sorry for that

--
bye bye Detlef
2022-08-04 12:02:52 +02:00
Vincent Lefevre
ef19711ba5 Use && rather than & for a Boolean operation. 2022-07-29 12:43:44 +02:00
Detlef Riekenberg
746560dc45 Do not fail with _Alignas(0) and _Alignas(1), used by autotools
Used by configure scripts, generated by newer GNU autotools
Autotools now checks for C11 and C99 compatibbility

--
bye bye Detlef
2022-07-28 18:30:54 +02:00
Detlef Riekenberg
bc12ab02c0 Accept -Wl,Map=filename.map
The parameter is stored in tccstate, but nothing more.

Used by multiple software packages.
Current tested example is OpenWatcom-v2

--
bye bye ... Detlef
2022-07-28 17:33:51 +02:00
herman ten brugge
2647dc063d Change plt_name size from 100 to 200.
I have jni code with very large symbol names (150 chars max).
This change avoids having names classes.
2022-07-25 13:00:15 +02:00
herman ten brugge
4589fdfad4 Fix netbsd elf problem
The dynamic linker on netbsd can only handle 2 PT_LOAD sections.
2022-07-25 12:55:26 +02:00
grischka
09808f327f tcc android-enabled (armeabi-v7a)
On an armeabi-v7a device (phone) in the termux app with
clang & make installed this passes all the tests.

Can be used as a cross compiler to create "native apps" as well.
Example 'config-extra.mak' for the cross arm-eabi-tcc:

  SYSROOT = <path_to_android_ndk...>/sysroot/usr
  TRIPLET = arm-linux-androideabi
  ANDRVER = 32

  ROOT-arm-eabi = $(SYSROOT)

  CRT-arm-eabi = {R}/lib/$(TRIPLET)/$(ANDRVER)
  LIB-arm-eabi = {B};{R}/lib/$(TRIPLET)/$(ANDRVER);{R}/lib/$(TRIPLET)
  INC-arm-eabi = {B}/lib/include;{R}/include/$(TRIPLET);{R}/include

  DEF-arm-eabi = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI
  DEF-arm-eabi += -DTARGETOS_ANDROID -DCONFIG_TCC_PIE -DCONFIG_NEW_DTAGS
  DEF-arm-eabi += -DCONFIG_TCC_ELFINTERP=\"/system/bin/linker\"

  # on unix replace ';' by ':'.
  $ ./configure && make cross-arm-eabi && make install
2022-07-24 09:51:32 +02:00
grischka
8e860702e4 tccelf: sort_sections()
Sort sections in separate function to allow variable
calculatiion of needed program headers.  Such execinstr
and relro cah have their own PT_LOAD header.

315 insertions(+), 370 deletions(-)
2022-07-24 09:45:48 +02:00
grischka
ebaa5c81f4 dynamic executables (PIE)
Allows to create dynamic executables, using the code path
for TCC_OUTPUT_DLL but add an .interp header (plus a FLAGS_1
entry in the dynamic section to make 'readelf' say "PIE")

Introduces TCC_OUTPUT_DYN as alias for TCC_OUTPUT_DLL.
There is no runtime option,  only one to configure:

    ./configure --config-pie

100 insertions(+), 76 deletions(-)
2022-07-24 09:44:50 +02:00
grischka
e460f7dbb2 tccelf: load libtcc1.a from library path
... rather than from tccdir.  Also allows to load cross
versions of bcheck.o etc. (if we would build them which
we currently don't).

18 insertions(+), 24 deletions(-)
2022-07-24 09:44:34 +02:00
grischka
d653cf01f3 tccelf: load objects first
It seems to make sense to load any helper objects (such as
bcheck.o) first, and then load standard libraries.

29 insertions(+), 29 deletions(-)
2022-07-24 09:42:28 +02:00
grischka
7d6979d452 tccelf: avoid lookup of _GLOBAL_OFFSET_TABLE_
Instead, return its symbol index from build_got_entries()
Also, copy dynamic symbols later when size of _GLOBAL_OFFSET_TABLE_
was already set and handle -rdynamic there too.
See commit 4c82b00342

5 insertions(+), 5 deletions(-)
2022-07-24 09:42:04 +02:00
grischka
c81519e1c4 tccgen: don't generate elf-symbols under nocode/NODATA
seems that symbols under nocode/NODATA should not produce
elf symbols at all, not just elf symbols with no size.
See commit 4c82b00342

5 insertions(+), 5 deletions(-)
2022-07-24 09:41:57 +02:00
grischka
e8adc64203 libtcc: extend tcc_add_dllref()
libtcc.c:
- integrate find_dllref loop into tcc_add_dllref()
tccelf.c:
- make sure a DT_NEEDED tag is put for versions even
  when the dll was not previously loaded.
Related commit 4c82b00342

48 insertions(+), 77 deletions(-)
2022-07-24 09:30:41 +02:00
grischka
7d31904247 tccelf: fix version patch for defined symbols
previous patch seems to work only for bcheck.o and only because
it's loaded after libraries (which is maybe wrong too).
See commit 4c82b00342

section_ptr_add() already clears area to zeros

4 insertions(+), 11 deletions(-)
2022-07-24 09:30:41 +02:00
Arthur Williams
8482682061 Define __TCC_BACKTRACE_ENABLED__ if backtrace is enabled
If the `-btN` was specified, then the __TCC_BACKTRACE_ENABLED__
macro will be defined. This provides a way for user code
to tell if tcc_backtrace is defined or not.
2022-07-23 15:12:15 -07:00
grischka
af1abf1f45 Revert "Fix wrong handling of strings..." (almost)
See commit e588b65390.
Was not "wrong" really, just different. But appears to be outdated.
Now disabled by default (top of tccpp.c: ACCEPT_LF_IN_STRINGS)
Also, in skipped code, just warn.

Also: cleanup "Optimize small structure copying on x86_64"
(commit 3715f1d7ee)
- remove some copy&paste coding (tccgen.c)
- RSI/RDI need to be preserved on windows
- simply don't use under bcheck (this is tinycc)
2022-07-16 00:41:37 +02:00
Ziyao
e588b65390
Fix wrong handling of strings which do not end properly at the end of line 2022-07-13 15:43:26 +08:00
herman ten brugge
a83b285685 Add extra locking in bound checking code 2022-07-09 12:10:08 +02:00
herman ten brugge
2c70652e04 Enabled test 112_backtrace
Changed script in Makefile for testcase 112
Used bound_struct_copy_count in lib/bcheck.c
2022-07-09 11:51:13 +02:00
Ziyao
2d210fef49
Skip test 112_backtrace on x86_64,because commit 3715f1d breaks
it.Commit 3715f1d makes the error message of bound check on x86_64
different from other platforms,which breaks the test process.But that
commit exactly works well.
2022-07-09 12:56:07 +08:00
Ziyao
3715f1d7ee
Optimize small structure copying on x86_64 2022-07-09 12:53:29 +08:00
Detlef Riekenberg
fe7ee1105c libtcc: Let "-Wl,*" also accept "--entry=xxx" as alias for "--e=xxx" 2022-07-08 00:18:14 +02:00
Michael Matz
73c22f831f Fix fallthrough of non-entered stmt expressions
commit ec5d94291 made is to that the nocode_wanted state from
inside a statement expression is retained after it.  That is wrong
if the statement expression can't be entered to start with.  In the
latter case the state from before the stmt-expr is the one we need.
2022-07-01 17:20:37 +02:00
Michael Matz
ebb4e71236 flexarray: Accept empty ones
See testcase, it's a GNU extension, but widely accepted (the
linux kernel uses it).  This got broken with 72b520e709.
2022-07-01 15:37:23 +02:00
Reinhard Urban
9712541156 Add missing ELFOSABI constants
from my github rurban/brandelf
2022-06-13 15:10:15 +02:00
herman ten brugge
cd627c6c40 Fix riscv assembler
riscv64-asm.c:
	asm_opcode: add return
	asm_parse_regvar: add abi register names

riscv64-tok.h:
	add abi register names
2022-06-07 20:53:14 +02:00
herman ten brugge
afc136262e Fix core dump in case -static is used 2022-05-26 15:41:52 +02:00
herman ten brugge
a4e0f7ef05 Fix bitfield long types for stabs/dwarf
Also made dwarf *leb128 fuctions a litlle bit faster.
2022-05-25 17:04:37 +02:00
herman ten brugge
e301a0ba8d Removed __bound_exit_dll from lib/bt-dll.c 2022-05-19 09:42:41 +02:00
herman ten brugge
aaec564a82 Fix bound checking dlcose problem
The main problem is that an application called dlclose and then
had a bound checking problem. The list of dll's in tccrun was
not updated an caused a crash.
Also fixed some minor other things.

tccdbg.c:
- Allow filenames like ../file.c
- Rewrite DWARF_ABBREV_MEMBER_BF/DWARF_ABBREV_MEMBER a bit

tccelf.c:
- Add call to __bt_exit. This solves problem when dlclose is called

tccrun.c:
- Rewrite rt_printline_dwarf a litlle to use opcode_length correctly
- Do not stop at DW_LNE_end_sequence
- Fix DW_LNE_set_address again. Works now in *bsd.

lib/bt-exe.c lib/bt-dll.c:
- Add __bt_exit/__bound_exit_dll

lib/bcheck.c:
- Add __bound_exit_dll
2022-05-19 07:40:14 +02:00
herman ten brugge
4c82b00342 Update for elflint problems
tccgen.c:
- When __FUNCTION__ is used and no code is generated use symbol len = 0.

tccelf.c:
- If library is present in verneed it should be in DT_NEEDED.
- @plt symbols should have size 0
- set _GLOBAL_OFFSET_TABLE_ st_size correct
- Remove version symbol if new value present

reported by elflint:

__FUNCTION__ problem:
  section [19] '.symtab': symbol 2134 (L.195) does not fit completely in referenced section [14] '.data.ro'
DT_NEEDED problem:
  section [26] '.gnu.version_r': entry 2 references unknown dependency
@plt symbols should have size 0:
  section [22] '.symtab': symbol 36557 (r_core_config_init@plt) does not fit completely in referenced section [14] '.plt'
_GLOBAL_OFFSET_TABLE_ size:
  section [44] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol size 4 does not match .got section size 736
Remove version symbol:
  section [25] '.gnu.version': symbol 86: version index 3 is for requested version
  This happened for example with bounds checking symbol malloc
2022-05-17 07:34:10 +02:00
Detlef Riekenberg
a4f9e3cf4c configure: Use the environment variable CC when compiling tcc (resend)
Using the environment CC is a common used feature to
select a compiler to build any software,
so it should be supported when building tcc.

The old way using the parameter --cc still works.

(resend)

Signed-off-by: Detlef Riekenberg <wine.dev@web.de>
2022-05-15 23:18:41 +02:00
herman ten brugge
0e47167cbe New dwarf update
tccdbg.c
- Fix typo in dwarf_file. This resulted in not finding correct include
  files.

tccrun.c:
- Change FILE_TABLE_SIZE to 512. Some files use very large includes.
- When a dll containted more then 1 file the pc was not calculated
  correctly.
2022-05-14 15:58:40 +02:00
herman ten brugge
53dd065daf Fix unicode compiler warning again 2022-05-14 15:55:27 +02:00
herman ten brugge
19cc80788d Fix unicode compiler warning
The compiler warned about the unicode_to_utf8 code.
I fixed it by giving an error. This is the same as gcc does.
2022-05-12 11:18:37 +02:00
herman ten brugge
e7396c99b0 Dwarf update
Some small updates in tccdbg.c found by checking readelf output from
gcc/clang.

- Change encoding type bool type
- Fix enum signed/unsigned
- Do not hash anon symbol
- Use correct filename/line_number for global variables
- Fix compiler warning in tcc_get_dwarf_info
- Use unsigned long long for array indexes
- Display correct first line of function in gdb
2022-05-12 08:15:28 +02:00
herman ten brugge
748e38ad99 Fix stupid typo. 2022-05-10 07:21:49 +02:00
herman ten brugge
9a81e6366b Fix vla type bug for stabs/dwarf
The wrong vla stabs code was accepted by gdb.
The dwarf vla code was fatal.
2022-05-10 07:16:38 +02:00
grischka
2caaff20fb tccdbg.c: new file
Better avoid global variables, at least in new code.

tccdbg.c hopefully should be logically identical to the
former parts in tccgen/elf.c (s1 tccstate added in some
places)

tccelf.c: dwarf linkage seems special per dwarf rather
than special per target.
2022-05-09 22:37:25 +02:00
grischka
56481d554f bored...
/* Use "-g" as alias for "-g1". Use "-g0" to disable debug */

So not using -g is now the alias for -g0 ?!?

This reverts commit 8759b2581d.
This reverts commit 3ce7bc6efc.
This reverts commit 5fb582ab7f.
This reverts commit aea68dbb40.
This reverts commit fa9c31c3db.
This reverts commit b3bebdb20a.
This reverts commit ecf8e5a00e.
This reverts commit fe6b5c08dc.
This reverts commit e2e5377e7b.
This reverts commit 1cd7998905.
2022-05-09 22:19:15 +02:00
Detlef Riekenberg
1cd7998905 tccmacho: avoid warnings with strncpy and always terminate the target string 2022-05-09 12:49:48 +02:00
herman ten brugge
0241120b54 Dwarf update for readelf
readelf complained about DW_AT_stmt_list and DW_AT_location.
For dwarf >= 4 we should use DW_FORM_sec_offset instead of DW_FORM_data4
and DW_FORM_exprloc instead of DW_FORM_block1.
This is fixed in tccgen.c

I also updated tccrun.c to use dwarf_read_1 instead of DW_GETC.
2022-05-09 08:04:37 +02:00
herman ten brugge
499cf2305b Add dwarf clang support
This if for clang (pre)release 15.0.0.

tccrun.c:
- update directory/filename read. clang has extra md5 section
- start with filename 0 instead of 1. clang starts at 0
- change dwarf_read_32/dwarf_read_64 into macros

x86_64-link.c:
- Add support for R_X86_64_DTPOFF64/R_X86_64_TPOFF64. Needed by clang

tests/tcctest.c:
- add prototypes for puts/alloca. clang fails with error
- disable other_constraints_test for clang. clang prints 1 instead of 0
2022-05-07 18:10:59 +02:00
herman ten brugge
18808e325f Update dwarf2 support
tccgen.c:
- add anon support. So tcc_state in tcc works now.
- add function pointer support
- remove DW_FORM_implicit_const from DW_TAG_pointer_type

tccrun.c:
- set initial file name
- correctly use pc in DW_LNE_set_address (see lib/bt-exe.c)
- add DW_LNE_define_file support (even if it is deprecated)

tccelf.c
- do not include debug/test_coverage information for stub functions

lib/bt-exe.c
- use num_callers=-1 to mark dll
2022-05-07 06:54:13 +02:00
herman ten brugge
f0df48fcdd Fix dwarf on 32 bits targets
Never do last minute commits :-(
2022-05-05 09:23:29 +02:00
herman ten brugge
2f2708a769 Add dwarf support
The new gcc12 release does not support stabs any more.
This was a good reason to add support for dwarf.

The stabs code still works and is used if configure option --dwarf
is not used.

Tested on x86_64, i386, arm, arm64, riscv64 with dwarf-5.
Some debuggers may not support dwarf-5. Try using older dwarf versions
i that case.
The tccmacho.c code probably need some support for dwarf.

arm-gen.c, arm64-gen.c, i386-gen.c, riscv64-gen.c, x86_64-gen.
- fix get_sym_ref symbol size

arm-link.c, arm64-link.c, i386-link.c, riscv64-link.c, x86_64-link.c
- add R_DATA_32U

libtcc.c:
- parse -gdwarf option

tcc.c:
- add dwarf option

tcc.h:
- add dwarf option and sections

tccelf.c:
- init dwarf sections
- avoid adding sh_addr for dwarf sections
- remove dwarf relocs for output dll
- add dwarf sections for tccrun

tccgen.c:
- add dwarf defines + global data
- add dwarf_* functions
- mix dwarf code with stabs code
- a trick is used to emit function name in .debug_line section so
  only this section has to be parsed instead of .debug_info and
  .debug_abbrev.
- fix init debug_modes

tccrun.c:
- add dwarf sections in rt_context
- init them in tcc_run
- add new dwarf code rt_printline_dwarf to find file/function

dwarf.h:
- New file

tcc-doc.texi:
- document dwarf

configure:
- add dwarf option

lib/Makefile
- change -gstabs into -gdwarf

lib/bt-exe.c, tests/tests2/Makefile, tests/tests2/126_bound_global:
- Add __bound_init call
- Add new testcase to test it
2022-05-05 09:10:37 +02:00
illiliti
d3e940c71c include/float.h: Define DECIMAL_DIG
Values were shamelessly stolen from musl libc. Needed for hare compiler.
2022-04-28 21:44:01 +03:00
Detlef Riekenberg
fa9c31c3db tcc.h: Extend search path for include, lib and crt.
This allows more tcc cross compiler to work out of the box
without a buildsystem-specific config-extra.mak
2022-04-28 17:36:10 +02:00
Detlef Riekenberg
9ac128c0bd Makefile: Add a comment with an option to debug the Makefile 2022-04-27 20:25:23 +02:00
Christian Jullien
5a3d1024d9 Update global help to tell that obj files are now optional with -ar driver 2022-04-19 07:53:19 +02:00
Ziyao
39ea340a31
Add option -e for setting ELF file's entry 2022-04-18 14:26:15 +08:00
Ziyao
0366924047
Add support of ldmxcsr and stmxcsr instructions on x86_64 and i386 2022-04-18 14:25:11 +08:00
Ziyao
8777ae984c
Allowing 'tcc -ar' to create empty archives 2022-04-18 14:23:03 +08:00
herman ten brugge
d3e4664629 Optimize prolog code on arm64
Only store registers that are needed in arm64 gfunc_prolog code.
Fix code in gen_bounds_epilog.
2022-04-15 20:11:18 +02:00
herman ten brugge
e86aae4f6d Add default case to relocate function for x86_64 2022-04-12 07:11:52 +02:00
herman ten brugge
c1725a8f6e Only define alloca on i386/x86_64 2022-04-12 07:07:40 +02:00
herman ten brugge
a5588501ab Fix vla support for arrays with no size 2022-04-12 07:03:33 +02:00
Detlef Riekenberg
aea68dbb40 arm-asm, arm64-link: Silence warnings for unused functions
The code needs to be fixed: use the functions or remove them.

arm-asm.c:
asm_parse_vfp_regvar()

arm64-link:
gotplt_entry_type()
create_plt_entry()

Signed-off-by: Detlef Riekenberg <wine.dev@web.de>
2022-04-12 02:11:06 +02:00
Detlef Riekenberg
ac42d6826b tccgen: Avoid warnings in callers of the type_size() function.
Warnings reported in in x86_64-gen.c and arm-gen.c:

warning: ‘align’ may be used uninitialized in this function [-Wmaybe-uninitialized]

Signed-off-by: Detlef Riekenberg <wine.dev@web.de>
2022-04-12 01:30:44 +02:00
Detlef Riekenberg
ecf8e5a00e tccelf: Avoid a compiler warning with snprintf
Target buffer must be larger as the format string + the replacement for %s
to avoid a warning [-Wformat-truncation=]

Signed-off-by: Detlef Riekenberg <wine.dev@web.de>
2022-04-12 01:06:10 +02:00
Detlef Riekenberg
fe6b5c08dc configure: Use the environment variable CC when compiling tcc
Using the environment CC is a common used feature to
select a compiler to build any software,
so it should be supported when building tcc.

The old way using the parameter --cc still works.

Signed-off-by: Detlef Riekenberg <wine.dev@web.de>
2022-04-12 00:33:35 +02:00
herman ten brugge
6bb41a05d7 Update for gcc12 on x86_64
gcc12 uses the xmm registers a lot more.

- save xmm0/xmm1 in gen_bounds_epilog
- align stack for call to (__bound_)memmove call in gfunc_call
2022-04-11 08:21:34 +02:00
Detlef Riekenberg
5fb582ab7f libtcc: Accept "-g0" to disable debug in addition to "-g", "-g1", "-g2" and "-g3"
This does not change our generated code.

Signed-off-by: Detlef Riekenberg <wine.dev@web.de>
2022-04-10 18:26:14 +02:00
Detlef Riekenberg
3ce7bc6efc Accept option "-Os" and define "__OPTIMIZE_SIZE__"
Some headers and source code change macros and
implementation, when __OPTIMIZE_SIZE__ is defined.

This does not change our generated code.

Signed-off-by: Detlef Riekenberg <wine.dev@web.de>
2022-04-10 17:32:38 +02:00
Detlef Riekenberg
b3bebdb20a libtcc: Allow more values for the -std= option
With this code, we can compile more projects,
who expect gcc or clang as compiler. (-std=gnu11 used in Makefiles)

As a further extension, it would be easy to disable gcc extensions

Signed-off-by: Detlef Riekenberg <wine.dev@web.de>
2022-04-10 00:55:11 +02:00
Detlef Riekenberg
8759b2581d Makefile: Use the .exe extension only on Windows for the c2str helper program
Signed-off-by: Detlef Riekenberg <wine.dev@web.de>
2022-04-07 02:18:19 +02:00
Detlef Riekenberg
e2e5377e7b Makefile: Add a doc target.
"make help" already documents a "doc" target,
but it was not present.

Signed-off-by: Detlef Riekenberg <wine.dev@web.de>
2022-04-01 21:26:55 +02:00
herman ten brugge
4a03f1fb20 Fix bounds checking struct return on arm/arm64 2022-03-28 09:07:09 +02:00
herman ten brugge
0244320b88 Add vla support for arrays with no size
Support vla arrays like arr[][s]

- tcc.h: add nesting parameter
- tccgen.c: use nesting to test for illegal vla's
- test/tcctest.c: add test case
2022-03-24 10:16:37 +01:00
Christian Jullien
750f0a3e3f As suggested by Herman, move comment to the next line otherwise it incorrectly handles --config-bcheck=no --config-backtrace=no 2022-03-23 09:03:54 +01:00
herman ten brugge
313855c232 Fix multi dimensional vla arrays on stack
There is no code generation in post_type for vla arrays. This code
generation has to be delayed until gen_function.

- post_type save code in type info.
- gen_function use this code to generate vla code.
- enable testcode for vla arrays.
2022-03-21 11:40:43 +01:00
herman ten brugge
8a3d0a0557 Fix multidimensional arrays on stack 2022-03-18 07:26:07 +01:00
herman ten brugge
4efcada291 Fix when bound checking and test coverage is used at the same time 2022-03-17 18:06:02 +01:00
herman ten brugge
184d845838 Fix riscv64 test 90 after struct init commit 2022-03-17 17:16:24 +01:00
herman ten brugge
291eccc154 Vla fix for 64 bits targets 2022-03-17 10:06:24 +01:00
grischka
719d96665e tccgen: Allow struct init from struct
Example:
    struct S {int x,y;}
        a = {1, 2},
        b = {3, 4},
        c[] = {a, b}, // new
        d[] = {b, (struct S){5,6}}; // new
2022-03-16 19:18:16 +01:00
grischka
0c6adcbe53 tccgen: multi-dimensional vla: bug fixes
fixes these cases:
   ptr - ptr             (-> ptrdiff_t)
   ptr +/- num           (-> ptr)
   sizeof (ptr+/-num)    (-> size_t)

Also some cleanups
2022-03-16 19:18:16 +01:00
grischka
ec5d94291c tccgen: accept array-size expressions in function paramters
Modify function parameter parser such that symbols are
put into token-table temporarily.  Benefits are:
- detects redefinitions, as with
    int foo(int a, int a);
- detects reserved symbols, as with
    int foo(int if);
- can parse expressions like
    int main(int argc, char *argv[argc + 1]);
- doesn't fix this one
    int main(int argc, char *argv[++argc]);

Also: fix unexpected "function might return no value"
with statement expression
    int f() { ({ return 0; }); }
2022-03-16 19:16:29 +01:00
Steffen Nurpmeso
917aad3bcf Add some missing fdopen(3) checks (Domingo Alvarez Duarte) 2022-02-28 21:19:41 +01:00
herman ten brugge
308d8d17dc Fix get thread id in lib/bcheck.c for freebsd
The api for getting the thread id is different for freebsd.
2022-02-21 09:15:43 +01:00
Christian Jullien
7225282ea5 Small patch from collective work to better support FreeBSD. 2022-02-20 15:45:24 +01:00
herman ten brugge
e9f59c804d Update for freebsd 13.0
Add __RUNETYPE_INTERNAL define in include/tccdefs.h
2022-02-08 18:53:16 +01:00
Christian Jullien
4e0e9b8f21 Add '#define __LITTLE_ENDIAN__ 1' which was missing for macOS port 2022-01-11 07:06:09 +01:00
herman ten brugge
d33b189427 Fix vla bug
This fixes a vla bug. Probably more fixes are needed.
Add testcode for bug.
2021-12-27 11:39:52 +01:00
herman ten brugge
1692060fb0 Fix cross compiling tcc on freebsd 2021-12-27 11:32:35 +01:00
herman ten brugge
6c0e0b998b Fix memcpy1/memcpy2 asm testcode on x86_64 2021-12-27 11:24:33 +01:00
Riccardo Schirone
027b8fb9b8 Add rpath to the library paths instead of state->rpath 2021-12-15 17:45:16 +01:00
Riccardo Schirone
d88857b210 If the DLL has a RPATH, use it when looking for NEEDED libraries 2021-12-15 17:30:25 +01:00
Alexander Sosedkin
da11cf6515 Don't skip weak symbols during ar creation
```
$ echo 'int __attribute__((__weak__)) f(void) { return 4; }' > w.c
$ tcc -c w.c -o w.o

$ tcc-old -ar rc w.a w.o; nm -s w.a  # previous behaviour, not indexed
w.o:
0000000000000000 W f

$ ar rc w.a w.o; nm -s w.a           # GNU binutils behaviour, indexed
Archive index:
f in w.o

0000000000000000 W f

$ tcc-new rc w.a w.o; nm -s w.a      # new behaviour, indexed
Archive index:
f in w.o

0000000000000000 W f
```
2021-10-30 16:07:00 +02:00
mingodad
1645616843 Revert "Move almost all global variables to TCCState, actually all tests pass on Ubuntu 18.04 x86_64"
This reverts commit af686a796b.
2021-10-22 07:39:54 +02:00
mingodad
2ce2dbcb09 Revert "Fix some errors on arm64-asm.c, rename some variables, fix several code style declarations"
This reverts commit 61537d899a.
2021-10-22 07:39:26 +02:00
mingodad
d33f582e25 Revert "Fix missing parameter"
This reverts commit 1a8fb94350.
2021-10-22 07:37:39 +02:00
mingodad
1a8fb94350 Fix missing parameter 2021-10-22 07:37:15 +02:00
mingodad
61537d899a Fix some errors on arm64-asm.c, rename some variables, fix several code style declarations 2021-10-22 07:20:00 +02:00
mingodad
af686a796b Move almost all global variables to TCCState, actually all tests pass on Ubuntu 18.04 x86_64 2021-10-21 20:09:42 +02:00
Ryan Burns
ca11849ebb Permit '=' character in configure options
By replacing the `-f 2` field selection with `-f 2-`, we select fields
2 and beyond, so that arguments containing the '=' character are not
truncated.

This option qualifier list format is POSIX standard and tested
to work with the `cut` program from:
* GNU coreutils
* macOS (FreeBSD)
* NetBSD
* toybox
* busybox
* uutils-coreutils

In my case, this is useful because I'm trying to use an installation
prefix which contains an equals sign.
2021-10-09 17:28:42 -07:00
coltrane
15e9b7384e Add few Windows API that can be used to detect the exact Windows version we are running on. 2021-09-16 08:52:35 +02:00
grischka
e97e108d0b tccpe: #pragma pack(push) - support this form 2021-09-01 19:36:24 +02:00
Tyge Løvset
c7a57bf1fa Prepended branch name to githash (tcc -v). WIN32: added githash support.
- E.g. "tcc version 0.9.27 mob:675046b (x86_64 Windows)"
- WIN32: Replaced compiler opt -O1 and -Os with -O2 (only 1% larger executable).
2021-08-21 09:10:56 +02:00
grischka
675046bd59 tcc/lib: reduce number of files
271 insertions(+), 292 deletions(-), -21 lines, -5 files
Also:
- tccdefs.h: WIN32: less (no) __builtins
- libtcc.c: simply ignore -arch
2021-08-03 22:49:18 +02:00
herman ten brugge
e538160a32 Fix netbsd build
Netbsd uses __UINTPTR_TYPE__ to detect gcc in machine/int_types.h
2021-08-03 11:32:54 +02:00
Christian Jullien
e449db5f1d macOS: if used, -arch option must match target 2021-08-02 14:21:28 +02:00
Christian Jullien
a951dc026f macOS: add -arch option to allow to bootstrap tcc with tcc on macOS. 2021-08-02 09:22:46 +02:00
grischka
dda95e9b0b WAIT/POST_SEM(): generalize interface (and more)
Currently used only with 'tcc_compile_sem' to protect
tcc_compile(),  but can be used with other semaphores

Also fix deadlock when tcc_enter_state() is called
recursively for the same state, for example with
tcc_warning() from #pragma comment(option,"...")

Also:
- libtcc.c: error1(): use cstr_[v]printf()
- tcc.h: set TCC_USING_DOUBLE_FOR_LDOUBLE for macho-arm64
  (rather than for macho-X86_64)
- tcc.h: define TCC_TARGET_MACHO on __APPLE__ by default
- tcc.h: cleanup TCCState, move DEFASM token stuff to tcctok.h
- tccgen.c: more static
- Makefile/tcc.c: review githash
- tccpe/tcctools: use read() instead of fgets() in pe_load_def()
  (all files opened by tcc for reading are now read via 'int fd')
- configure/win32: don't preset CONFIG_TCCDIR (to allow to override it)
- tcc.c -bench: do not include output/run-time
2021-08-01 20:33:31 +02:00
grischka
4b2c6cf3a4 -W[no-]error...: features by shrinkage
136 insertions(+), 226 deletions(-), less 90 lines (except tests)
only one set_flag() function required
* can now turn off specific errors: -Werror -Wno-error=option
* new interface: tcc_warning_c(warn_option)("format", args...);
* new warning: -Wdiscarded-qualifiers (on by default)
* new variable 'warn_all' for conditional warnings with -Wall
see also the tests
2021-07-31 21:45:33 +02:00
Sam Ellicott
931a146591 tccdef.h additons for riscv64 newlib stdint 2021-07-29 22:36:53 -04:00
Steffen Nurpmeso
2709b7ab03 -W[no-]error: fix previous (sigh) 2021-07-27 23:19:36 +02:00
Steffen Nurpmeso
49cd6f59b2 -W[no-]error: rid of TCCState.warn_none, too; and adjust -h/-hh output 2021-07-27 20:55:58 +02:00
Steffen Nurpmeso
0d59ac4817 -W[no-]error: fix previous 2021-07-27 20:00:20 +02:00
Steffen Nurpmeso
0c16762418 -W[no-]error=X: gcc compat: when disabling X again, do not unset the warning 2021-07-27 19:48:29 +02:00
Christian Jullien
b1d9de6794 [macOS] fix format warning 2021-07-27 07:54:46 +02:00
Steffen Nurpmeso
a7a13896b3 Add -W[no-]error=OPTION specific abortions 2021-07-27 00:37:22 +02:00
grischka
eadcee6501 macos: yet another tbd adjustment
configure:
- re-enable apple M1-arm64
- however, with --cpu=x86_64,  set -arch in CFLAGS/LDFLAGS too
  (assume rosetta)

Makefile:
- re-enable osx cross-test (Please do not disable tests)

tcc.h
- set TCC_IS_NATIVE for TCC_TARGET_MACHO on __APPLE__
- apply TCC_USING_DOUBLE_FOR_LDOUBLE for x86_64-osx

libtcc.c:
- cleanup tcc_add_file_internal()
- new function char *tcc_load_text(int fd); and use it for tbd files
2021-07-25 20:55:05 +02:00
Sushant Pandurangi
ecb384ac0c Fix 'unused function' warning on non-macOS targets 2021-07-17 13:42:54 +02:00
Brian Callahan
46bf3f940c Add register definitions for OpenBSD/riscv64 2021-07-09 12:16:18 -04:00
Christian Jullien
ab13f1a25a On Big Sur M1, force a x86_64 native build and count on Rosetta to make job as arm64 is not yet supported. 2021-07-08 09:37:37 +02:00
herman ten brugge
6e76d894fe Fix macOS memcheck problems 2021-07-07 10:05:23 +02:00
Christian Jullien
91a956823e [macOS] Add VT_LDOUBLE special case for Rosetta to handle --cpu=x86_64. 2021-07-07 09:50:20 +02:00
Christian Jullien
592cf7fb25 Temporary remove osx cross build which is broken, at least on Windows. 2021-07-07 09:09:12 +02:00
Christian Jullien
b964fc6922 dlopen does not exist on Windows, recent macOS adds a dlopen call which is skipped on Windows. 2021-07-07 09:08:15 +02:00
Sushant Pandurangi
588d64c538 (merge) macOS11+ dynamic linker support 2021-07-06 22:54:28 +02:00
Sushant Pandurangi
cca4ece0a8 macOS: get active SDK path from xcode-select 2021-07-06 22:48:38 +02:00
Sushant Pandurangi
d5e4b258e1 Minor fixes for gnu90 compatibility 2021-07-06 15:59:12 +02:00
Tyge Løvset
c4a2c52411 Added __faststorefence() MSVC intrinsic (required e.g. by sqlite3). 2021-07-04 13:32:55 +02:00
Sushant Pandurangi
33fa3a4d41 macOS 11: tcc -run using dyld shared cache 2021-07-04 11:07:48 +02:00
Sushant Pandurangi
f6fb4d0cf1 macOS 11: link using dyld shared cache
Supports linking using .tbd definitions found in the default installed
command-line tools SDK or Xcode.app SDK. Only for creating executables
(not yet for `tcc -run`).
2021-07-04 11:06:55 +02:00
Christian Jullien
e3a0eb5089 Minor change, help message starts with lowercase as other help strings. 2021-07-02 07:01:13 +02:00
Arthur Williams
ee75521dd5 Support -M, -MM, and -MMD
Add support for some more options to generate dependency fragments.
-M is likes -MD but doesn't compile anything so the command won't fail
when just supplied a file without all the relevant libs.
-MM and -MMD are like their counterparts but skip system libs.

Note the behavior of -MD has changed to include system libs. Use -MMD
for the old behavior. This matches gcc's corresponding flags
2021-07-01 01:44:34 -05:00
Arthur Williams
64d29c942a Have '-MF -' write to stdout
If a dash ("-") is specified to -MF, write to stdout instead of a file
called "-"
2021-07-01 01:44:23 -05:00
Arthur Williams
24d35faed2 Use grep -q instead of grep --quiet to be more portable 2021-07-01 01:44:23 -05:00
Christian Jullien
39d586d7fc gcc compiles .h files as .c source code, tcc now does the same and no longer complains with "unrecognized file type". It is however adviced to use "-x c" option which exists for this purpose in gcc and was supported by tcc. 2021-06-28 13:07:29 +02:00
herman ten brugge
b5d4b908c4 Fix function call on arm64 and riscv
arm64-gen.c/riscv64-gen.c
- Copy code from x86_64-gen.c (fetch cpu flag before generating any code)

tests/tcctest.c:
- Add test code
2021-06-22 07:38:39 +02:00
herman ten brugge
0378168c13 Fix macro processing
The code:

printf("%d\n", CALL(CONST));

did not work because we did not check for TOK_PLCHLDR.
2021-05-04 11:22:11 +02:00
Tyge Løvset
3564c47e52 Relicensing TinyCC 2021-04-27 11:56:43 +02:00
Danny Milosavljevic
431a74a446 Relicensing TinyCC 2021-04-26 19:34:27 +02:00
Danny Milosavljevic
9b76a64f96 riscv64-asm: Implement asm_clobber 2021-04-23 20:23:45 +02:00
Danny Milosavljevic
468f338e23 riscv64-asm: Optimize gen_le32 2021-04-23 20:23:45 +02:00
Danny Milosavljevic
99189ea707 riscv64-asm: Implement asm_parse_regvar 2021-04-23 20:23:45 +02:00
Danny Milosavljevic
b28bf50d2b riscv64-asm: Add beq, bne, blt, bge, bltu, bgeu 2021-04-23 20:23:45 +02:00
Danny Milosavljevic
9c0760a4d4 riscv64-asm: Add lb, lh, lw, lbu, lhu, ld, lwu, sb, sh, sw, sd 2021-04-23 20:23:45 +02:00
Danny Milosavljevic
1e37ec4917 riscv64-asm: Add add, addi, sub, addw, addd, addiw, addid, subw, subd, xor, xori, or, ori, and, andi, slt, slti, sltu, sltiu 2021-04-23 20:23:45 +02:00
Danny Milosavljevic
8b1a89fbdf riscv64-asm: Add sll, slli, srl, srli, sra, srai, sllw, slld, slliw, sllid, srlw, srld, srliw, srlid, sraw, srad, sraiw, sraid 2021-04-23 20:23:45 +02:00
Danny Milosavljevic
0b1cc489e1 riscv64-asm: Add lui, auipc 2021-04-23 20:23:45 +02:00
Danny Milosavljevic
e5a898e510 riscv64-asm: Add rdcycle, rdcycleh, rdtime, rdtimeh, rdinstret, rdinstreth 2021-04-23 20:23:45 +02:00
Danny Milosavljevic
4891ab71a0 riscv64-asm: Add fence, fence.i, scall, sbreak, ecall, ebreak, wfi 2021-04-23 20:23:45 +02:00
Danny Milosavljevic
7f3114ebba riscv64-asm: Remove asm_error 2021-04-23 20:23:45 +02:00
herman ten brugge
1432574b2b Fix make lib/stdatomic.c gcc compatible 2021-04-14 12:22:18 +02:00
herman ten brugge
f8e50d23f5 Make lib/stdatomic.c gcc compatible 2021-04-14 11:59:57 +02:00
herman ten brugge
0f0f701212 Fix va_arg fox x86_64 2021-04-13 09:23:13 +02:00
herman ten brugge
d64923c7b4 Fix testcase 125 fox x86_64 2021-04-13 09:13:25 +02:00
Christian Jullien
035ae7d735 Fix Makefile as suggested by Urs Janßen 2021-04-09 14:21:36 +02:00
grischka
48df89e10e stdatomics: tidy & cleanup
- remove any error messages that were just for debugging the
  templates really
- don't use c99 in tcc (array designators etc.)
- remove memory model type (cannot be an own type really)
  and move memory model defines from built-in to stdatomics.h
- apply normal casts to non-pointer atomic_function arguments
- tidy the library support
- add some tests for errors/warnings

Also:
- Makefile: move GIT_HASH stuff from CFLAGS to DEFINES and into
  main section (away from what is included by tests for example)
- tccelf.c/tccgen.c: avoid some warnings with newer GCC
2021-04-09 10:47:35 +02:00
Dmitry Selyutin
4bb3b3cec7 stdatomic: simple counter test 2021-04-05 20:57:05 +03:00
herman ten brugge
aa7727964b plt-reloc fix for macos 2021-04-02 12:51:38 +02:00
Christian Jullien
affd736f19 Add 'modified' before hash when tcc is built from a patched mob version. 2021-04-02 08:00:31 +02:00
Christian Jullien
f68b39b922 Surround hash code with double quotes 2021-03-31 23:15:47 +02:00
Christian Jullien
65d00b13d5 tcc -v displays short hash to ease detection of source version used to compile tcc 2021-03-31 22:24:29 +02:00
Dmitry Selyutin
47da8e450e stdatomic: ld/st/xchg/cmpxchg on simple types
Some complex types can still be small and simple enough to fit into
register. Other compilers allow some operations on these types, and it
seems to be quite a reasonable choice. From now on, we should be able
to compile the following artificial example:

    struct combo {
        uint16_t lo;
        uint16_t hi;
    };

    struct combo load(const _Atomic(struct combo) *atom)
    {
        return atomic_load(atom);
    }

    void store(_Atomic(struct combo) *atom, struct combo value)
    {
        atomic_store(atom, value);
    }

    struct combo xchg(_Atomic(struct combo) *atom, struct combo value)
    {
        return atomic_exchange(atom, value);
    }

    bool cmpxchg(_Atomic(struct combo) *atom,
            struct combo *cmp, struct combo xchg)
    {
        return atomic_compare_exchange_strong(atom, cmp, xchg);
    }

This might be useful for some corner cases, though it is quite likely
that many programmers will prefer operating on a single 32-bit value
instead of using the structure consisting of 16-bit pair.

Things will work as long as the overall structure size happens to be
the same as for any integer type we support in atomics.
2021-03-25 22:45:58 +03:00
Michael Wilder
82b0af7450 Fix empty initializer compile error on win32 2021-03-18 18:45:28 -04:00
Dmitry Selyutin
9ed3de91a2 stdatomic: i386/x86_64 support 2021-03-17 00:33:59 +03:00
Dmitry Selyutin
806b3f987e stdatomic: fix warnings 2021-03-17 00:29:57 +03:00
Dmitry Selyutin
1ff8679e79 stdatomic: refactor parser and generator 2021-03-09 12:24:08 +03:00
Christian Jullien
d0d0c8b688 [macOS]: arm64, define both __aarch64__ and __arm64__ which are tested by standard include files. WIP 2021-02-21 11:56:16 +01:00
Christian Jullien
310d49668e [macOS]: arm64, add OBJ-arm64-osx lib object list. 2021-02-21 11:32:59 +01:00
Christian Jullien
ac8af47d7f [macOS]: arm64, correctly find clang which is not a symblink from cc 2021-02-21 10:54:49 +01:00
Christian Jullien
e8bff295f9 [macOS]: arm64, very early stage of Big Sur M1 native port. 2021-02-21 08:38:39 +01:00
grischka
97800177c9 tccgen: gen_cast(): detect 'cast from void' error 2021-02-19 09:55:40 +01:00
grischka
72f1dea537 tccelf: use rodata_section, use more rodata in tcc itself
libtcc.c: add -Wwrite-strings to -Wall
tccgen.c: ro float-consts, string-consts, ro arrays if base type is
tccpe.c: merge IAT with rodata
tccrun.c: mprotect rodata accordingly. free section data after copy
x86_64.c: do not use got for static data.
tcc -bench: show data.rw/ro

Probably STB_LOCAL should never get to put_got_entry(), and currently
it doesn't seem to happen (See "Hack Alarm" there)

Other files: use more ro-data in tinycc
2021-02-18 14:43:34 +01:00
grischka
02795106e1 tccelf: use plt-reloc instead of relocplt 2021-02-18 14:42:59 +01:00
grischka
e4f151c4cd tccgen: fix "Allow declared arrays to be initialized..."
See 355897a920
2021-02-18 14:04:53 +01:00
CodeHz
a1d10c8bde
Fix unnecessary symbol collision 2021-02-18 20:41:47 +08:00
Michael Matz
5201312cb2 Fix segfault with nested flex array structs
when used with string initialization the size of nested struct flex
array member was tested too late for < 0.

GCC accepts but discards such initializers (the flex array member will
become zero sized).  TCC supports flex arrays members only in
top-level structs and gives an error in this case.
2021-02-16 00:01:28 +01:00
herman ten brugge
3658c29b43 Add config pie option
Allow configure --config-pie for netbsd arm
2021-02-15 19:14:48 +01:00
herman ten brugge
87dcba16eb Fix tcov align and lock 2021-02-15 19:10:13 +01:00
herman ten brugge
f5b8444739 Fix declared arrays without size 2021-02-15 19:05:26 +01:00
Dmitry Selyutin
dd5b546bf7 stdatomic: atomic_init routine 2021-02-14 22:22:27 +03:00
Arthur Williams
355897a920 Allow declared arrays to be initialized without an explicit size
When defining an array with non-explicit size, one would get
"incompatible types for redefinition of 'array' if the array was already
declared with a different size.
For example:

    extern int array[2];
    int array[] = {1};

would fail to compile with tcc. Instead the above is now equivalent to:
    int array[] = {1, 0};
2021-02-13 19:18:08 -08:00
Michael Matz
d7f2775af8 Fix endless recursion due to type scoping
this change fixes building of invalid types.  The inner scope
struct P is return type of the forward decl foobar.  The outer scope
foobar() call implicitely declares that function again, with int
return type; overall this leads to access within the sym free list,
effectively building up a type directly referring to itself, leading
to endless recursion later.  The testcase is:

void n(void)
{
    {
      struct P {
          int __val;
      };
      struct P foobar(); // 1
    }
  foobar();  // 2
}

I've not included it in tests2 for now, because tcc accepts this.
Ideally we would like to reject it (as 'int foobar();' is incompatible
with the earlier decl).  clang also accepts it, but only because it's
not handling (1) above as an implicit decl of foobar (it warns, and
with -pedantic also warns about the type incompatiblity).  GCC rejects
this.

Implementing that in tcc requires some surgery, as we need to differ
between these cases:

  {  struct P foo(int); // 1
     foo();        // no implicit decl, call to foo from 1
  }

and

  { { struct P foo(int); // 2 }
    foo();         // implicit decl, _incompatible_ with 2
  }
2021-02-13 03:29:43 +01:00
Danny Milosavljevic
24c94fff09
arm-asm: Add vcvt 2021-02-13 01:03:41 +01:00
Danny Milosavljevic
f1fb23a661
arm-asm: Update comment 2021-02-13 01:03:39 +01:00
Michael Matz
30814dfacf Don't use stale section data pointers
put_elf_reloca might reallocate the section into which we point,
so don't remember the pointer just the offset.
2021-02-13 00:37:12 +01:00
Michael Matz
468e59206b Clear vtop.sym if saving on stack
normally the sym slot is meaningful only with VT_SYM.  But we also
use it when mentioning a decl for inline asms with register vars,
conditional on being a VT_LOCAL entry.  So when generating VT_LOCAL we
need to reset .sym as it might contain stale entries from the cmp_op
fields.
2021-02-13 00:24:29 +01:00
Michael Matz
ce8814cdd6 Avoid array overflow
with fuzzed source code we might run into this with idx out of bounds.
We're going to error out on this later, but let's not access
out-of-bounds elements.
2021-02-12 23:46:21 +01:00
Michael Matz
c4ae326a1d Revert "Long double Constant problem"
This reverts commit 405aef9155.
It doesn't compile (init_putv has no 'f1') and isn't necessary with a
compiler doing proper value initialization.
2021-02-12 22:52:05 +01:00
ayush-varshney
405aef9155 Long double Constant problem 2021-02-11 08:49:58 +01:00
Michael Matz
fbef90a703 Fix a VLA problem
see testcase, reduced example of a situation reported by
Kyryl Melekhin in https://github.com/kyx0r/neatvi/ .
Problem is that setting up the VLA sp-save in a scope that isn't
entered at runtime leaves traces of it in outer scopes that then
try to restore the stack pointer from uninitialized slots.
2021-02-03 04:30:11 +01:00
Danny Milosavljevic
d6f2d58158
Relicensing TinyCC 2021-02-02 14:07:43 +01:00
Riccardo Schirone
ad16628c9e Make sure to escape paths in generated make dependencies
If spaces are not escaped when generating the make dependencies file,
then if one of the dependencies has a space it would be interpreted as
two separate targets by Make, instead of just one.
2021-01-30 00:51:15 +01:00
Danny Milosavljevic
2ac8568503
arm-asm: Support immediate values without "#" (Unified Assembly Language) 2021-01-28 16:32:31 +01:00
Dmitry Selyutin
458457590d stdatomic: fix atomic_init parameters 2021-01-28 00:13:53 +03:00
Dmitry Selyutin
9d862be1e7 stdatomic: fix is_memory_model check 2021-01-28 00:13:07 +03:00
herman ten brugge
1c255baad5 test coverage update
Add myself to RELICENSING file
    Use locking when writing tcov file
    Fixed sometimes last line of function not shown
    Merge tcc_tcov_add_file and tcc_add_tcov
    Allow absolute file names
    Count case labels with no code better
2021-01-27 13:27:10 +01:00
Dmitry Selyutin
65773a5300 stdatomic: c11 prefix; migrate to models macros 2021-01-27 13:33:32 +03:00
Dmitry Selyutin
5053fd03a7 stdatomic: memory models as macros 2021-01-27 13:26:48 +03:00
Dmitry Selyutin
02ea864ad2 stdatomic: deplusification; LLVM notice 2021-01-27 13:25:12 +03:00
Dmitry Selyutin
f2e7742aea stdatomic: stdatomic.h header 2021-01-27 00:48:46 +03:00
Dmitry Selyutin
719a6b3a16 stdatomic: emit function calls 2021-01-26 22:37:44 +03:00
Dmitry Selyutin
a110287c31 stdatomic: atomic builtins parsing support 2021-01-26 22:37:44 +03:00
grischka
557b4a1f6d configure chmod 755 etc.
lib/tcov.c:
- can't be cross-compiled (needs stdio.h)
- can be included in libtcc1.a

Reason why bt-xxx.o/bcheck.o are linked separatly is because we
don't want then to linked into exe's and dlls at the same time.
2021-01-26 18:44:37 +01:00
Danny Milosavljevic
25628cffe5
arm-asm: Add vmsr, vmrs 2021-01-26 14:25:39 +01:00
Danny Milosavljevic
1c9d999114 arm-asm: Implement "vmov.f32 Sn, Rd", "vmov.f32 Rd, Sn", "vmov.f64 Dm, Rd, Rn", "vmov.f64 Rd, Rn, Dm" 2021-01-26 03:31:33 +01:00
Danny Milosavljevic
90343eba3a arm-asm: Mostly factor out VFP register reference parsing to parse_operand 2021-01-26 03:24:09 +01:00
Danny Milosavljevic
0416594071 arm-asm: Add vmov 2021-01-25 21:56:52 +01:00
Danny Milosavljevic
b82e52a497 arm-asm: Add vmla, vmls, vnmls, vnmla, vmul, vnmul, vadd, vsub, vdiv, vneg, vabs, vsqrt, vcmp, vcmpe 2021-01-25 21:56:52 +01:00
Danny Milosavljevic
104037a4c5
arm-asm: Raise error if user tries to use a shift instruction with an immediate source operand 2021-01-25 00:54:01 +01:00
grischka
1ed4b6ba1a debug_modes, re-unalign, cleanups
tccgen.c: debug_modes
- don't waste debug function calls during normal execution.
libtcc.c:
- mem_debug: no C99 features in tcc please, for example
  ({compound expressions}): do not use.
tccgen.c: struct_layout:
- unaligned access is completely ok for most targets.
- Moreover the patch was triggering single byte mode even
  for normal aligned access (as with tcc's SymAttr)

static Sym label: don't do this

arm-gen.c:
- use some #ifdefs to explain some code
tccpp.c:
- cleanup UCN chars
libtcc.c:
- replace openbsd library search
configure:
- cleanup strip fallouts
tccgen.c:
- expr_cond(): remove an exotic optimization that eventually
  got fixed to do the contrary by a gv(RC_InT)
- pop_local_syms(): remove some args
- init_putv() : use write##le functions to avoid cross-compiler
  unaligned access
- __bt_init(): remove unused param 'mode'
2021-01-24 18:00:33 +01:00
herman ten brugge
5043268cb1 Fix unaligned access arm (openbsd)
libtcc.c:
Fix unaligned load/store from magic3

tccgen.c:
For packed struct allways use single byte code
If field does not start at at align check it
Align stack correctly with vla
2021-01-24 11:28:26 +01:00
herman ten brugge
38eaf9b3a7 Fix compiler warnings utf8 code 2021-01-23 19:21:33 +01:00
herman ten brugge
b40a88ea46 Use arm assembler in lib dir 2021-01-23 19:08:59 +01:00
herman ten brugge
bc6c0c34c1 implement test coverage
I have implemented the -ftest-coverage option. It works a bit different
from the gcc version. It output .tcov text file which looks almost the
same as a gcov file after a executable/so file is run.

Add lib/tcov.c file
Modify Makefiles to compile/install it
Add -ftest-coverage option in tcc.c/tcc.h/tcc-doc.texi
Add code to tccelf.c/tccgen.c/tccpe.c
Add gen_increment_tcov to tcc.h/*gen.c

unrelated changes:
Add sigemptyset in tccrun.c
Fix riscv64-gen.c tok_alloc label size
2021-01-23 18:17:38 +01:00
Danny Milosavljevic
66de1550ab
arm-asm: Add vpush, vpop, vldm, vldmia, vldmdb, vstm, vstmia, vstmdb 2021-01-23 14:57:33 +01:00
Danny Milosavljevic
e350058532
arm-asm: Add svc 2021-01-23 14:20:06 +01:00
Danny Milosavljevic
2e87eb18ab
arm-asm: Improve build with MSVC 2021-01-21 21:56:10 +01:00
Danny Milosavljevic
3fc55e15e8
arm-asm: Enable VFP when invoking GNU as for testing VFP instructions 2021-01-21 20:33:04 +01:00
Danny Milosavljevic
cdbb55396c
arm-asm: Add vldr, vstr
Also add s0...s31, d0...d15
2021-01-21 18:15:19 +01:00
Danny Milosavljevic
31dde11ad5
arm-asm: Add ldc2, ldc2l, stc2, stc2l 2021-01-21 16:42:31 +01:00
Danny Milosavljevic
7900a6bb61
arm-asm: Add ldc, ldcl, stc, stcl 2021-01-21 16:42:28 +01:00
Danny Milosavljevic
d1a6c4aefa
arm-asm: Add mcr, mrc 2021-01-21 16:42:23 +01:00
Danny Milosavljevic
a1dad7a9f7
arm-asm: Add cdp2
Also allow instructions without condition code in the first place
2021-01-21 16:42:20 +01:00
Danny Milosavljevic
036a7fe7d4
arm-asm: Add cdp
Also add p0...p15 (coprocessors), c0...c15 (coprocessor register aliases)
2021-01-21 16:42:16 +01:00
Christian Jullien
593bed9b52 Fix arm NetBSD cross compilation 2021-01-19 08:58:24 +01:00
Danny Milosavljevic
d60d2bb60e
arm-asm: Make "!" optional in asm_block_data_transfer_opcode 2021-01-18 18:58:08 +01:00
Petr Skocik
704c8163fd re-add accidentally deleted printf("\n"); to tests2/97*.c 2021-01-18 08:32:50 +01:00
Petr Skocik
ffb95c2e0c Better handling of UCNs in strings
As the standard requires, take 4 hex digits after the \u opener of a
Universal Character Name, or take 8 hex digits after \U, but reject
smaller counts and don't consume more (https://port70.net/~nsz/c/c11/n1570.html#6.4.3,
https://port70.net/~nsz/c/c99/n1256.html#6.4.3).

The unicode codepoint used to get truncated to 1 byte. Now it gets expanded into UTF-8,
matching gcc & clang behavior on Linux.

TODO: Universal character names should also be supported in identifiers,
as in, e.g., char \u010dau_sv\u011bte[]="čau_světe";
2021-01-18 00:49:24 +01:00
herman ten brugge
6b614c4deb OpenBSD: arm fix
Disable warning softfloat. OpenBSD works fine.
save/restore s0-s15 during memcpy call for structs
update configure script. Works now on raspberry pi/All BSD
Add eabi_mem.. functions in armeabi.c for OpenBSD
Fix fp register in tccrun.c for OpenBSD
2021-01-17 20:43:15 +01:00
Christian Jullien
debe8d013d Use $targetos instead of a second call to uname 2021-01-17 11:45:23 +01:00
Christian Jullien
a2987fef19 configure automatically detects correct arm configuration on NetBSD 2021-01-17 09:02:00 +00:00
Christian Jullien
53f7d8baf4 conftest correctly detects NetBSD and OpenBSD for TRIPLET_OS 2021-01-17 08:49:37 +01:00
Christian Jullien
f5f8326531 FreeBSD: arm port is fully supported and added to cross list 2021-01-16 16:25:22 +01:00
herman ten brugge
5aba20f270 BSD: arm support
Support OpenBSD/FreeBSD/NetBSD on asm.

move PAGESIZE to tcc.h and use _SC_PAGESIZE (netbsd/arm has 8192 pagesize)

arm:
- fix cmp instruction for qemu (raspberry pi works without patch?)
- increase start address/size
- use large plt size
- add return R_ARM_PREL31
- add R_ARM_TARGET1 to prepare_dynamic_rel
- add gcc_s to FreeBSD (unwind code)
- do not use __clear_cache on bsd (sometimes bad system call)
- do stack unwinding on bsd
- test/tcctest.c: use %lld %llu on bsd
2021-01-16 07:01:59 +01:00
Danny Milosavljevic
757eccd1d2
arm-asm: Raise error if user tries to use PC for offset register of single data transfer 2021-01-14 23:16:38 +01:00
Danny Milosavljevic
007839597f
arm-asm: Implement ldr and str with shifted register offset
Factor out asm_parse_optional_shift
2021-01-14 23:16:31 +01:00
Christian Jullien
1d7b233562 Remove strip logic form configure script, keep a deprecated warning message when --strip-binaries is still used. 2021-01-14 07:10:41 +01:00
herman ten brugge
13f6e8a866 OpenBSD: arm support typo (WIP) 2021-01-13 19:58:19 +01:00
herman ten brugge
96e3923239 OpenBSD: arm support update (WIP) 2021-01-13 19:41:04 +01:00
Christian Jullien
20dbfe99b8 --strip-binaries is deprecates, build never strips, use 'make install-strip' to install stripped binaries 2021-01-13 18:51:23 +01:00
herman ten brugge
23989cbcf3 OpenBSD: arm support (WIP) 2021-01-13 13:20:36 +01:00
Christian Jullien
d5c78ce655 Add more supported systems for cross test 2021-01-13 09:34:37 +01:00
Christian Jullien
c35f61b958 Fix ./configure strip test 2021-01-13 07:56:05 +01:00
Christian Jullien
d7d470b357 ./configure always stripped binaries even if --strip-binaries was unset 2021-01-13 07:27:46 +01:00
herman ten brugge
56f74f2eeb Add shstrtab name in tccelf.c
Last commit removed shstrtab which make gdb/readelf unhappy.
2021-01-12 21:41:41 +01:00
grischka
62c0c4c77a tccelf.c: factor out elf_output_obj()
The small common parts within elf_output_file() aren't
worth the many #ifdefs.  Also, set section sizes and
allocate section names in 2 separate functions.
2021-01-12 18:39:35 +01:00
herman ten brugge
c74c6ed61a Serveral updates
arm-gen.c:
- remove fr parameter from load_value

tccelf.c:
- update comment and remove check for sh_size

tests/boundtest.c:
- fix testcase 16/17
2021-01-12 18:06:23 +01:00
herman ten brugge
28646b559d fix cross compiling on openbsd 2021-01-12 09:59:52 +01:00
herman ten brugge
ecdee4a697 arm64: Fix loading from constant address 2021-01-12 08:46:05 +01:00
Christian Jullien
00d467d44c OpenBSD: use portable strtoll instead of strtonum to allow cross-compilation test 2021-01-12 08:12:40 +01:00
herman ten brugge
4d254312be Remove gaps between RELX sections update
Update file_offset as well
2021-01-12 07:40:45 +01:00
Christian Jullien
64d5db7635 *BSD: fix broken Makefile on all BSD systems. 2021-01-12 07:08:39 +01:00
herman ten brugge
c9bdfcedb4 Remove gaps between RELX sections
These gaps are a result of final_sections_reloc. Here some relocs are removed.
The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
is illegal.
2021-01-12 06:59:51 +01:00
herman ten brugge
cd91ea658a OpenBSD: x86 update 2021-01-11 19:26:10 +01:00
grischka
bbc7070c82 make test: run cross-test always
To see inconsistencies when they happen.
2021-01-11 15:17:26 +01:00
Christian Jullien
42220676d7 OpenBSD: x86 use few clang compatible C types 2021-01-11 12:19:09 +01:00
Christian Jullien
db6dd66047 OpenBSD: -arm- Add more R_ARM* constants in elf.h. 2021-01-11 07:21:57 +01:00
Christian Jullien
6f27eca785 OpenBSD: Add 2 new R_ARM constants to be handled by arm-link.c 2021-01-10 19:02:55 +01:00
Christian Jullien
1018ee8749 OpenBSD: aarch64 99% working, armv7 WIP. 2021-01-10 11:56:14 +01:00
Christian Jullien
ef7c4388e7 OpenBSD: elfinterp location looks the same for all architectures. i386 WIP 2021-01-10 07:23:03 +01:00
Christian Jullien
0e74965d7f make install always strips, only install-strip target should do 2021-01-10 05:57:52 +01:00
herman ten brugge
68744e3260 OpenBSD: Add static link support 2021-01-09 20:35:54 +01:00
Christian Jullien
a3524bd780 OpenBSD: Fix warning and other *BSD builds. 2021-01-09 17:36:13 +01:00
Christian Jullien
e6d15a5df1 OpenBSD: add a workaround to find the versioned shared lib as no .so symlink exist. 2021-01-09 15:38:26 +01:00
Christian Jullien
5f9d4ad144 OpenBSD: crtbeginT.o does not exist on thsi system as with other *BSD systems. 2021-01-09 14:14:05 +01:00
Danny Milosavljevic
aed4941e6b
arm-asm: Add ldrh, ldrsh, ldrsb, strh 2021-01-08 13:52:25 +01:00
herman ten brugge
f44332c891 update arm text relocations
Avoid absolute text relocations and use relative/got addressing.
This makes code work on netbsd where this is required. (No DT_TEXTREL)
2021-01-06 09:48:15 +01:00
Christian Jullien
cb788d72c7 NetBSD: Minor edit, keep tab style of previous line 2021-01-06 07:10:56 +01:00
Christian Jullien
760024bde9 NetBSD: Trying to fix reloc error 38 on arm - WIP 2021-01-06 07:02:19 +01:00
Danny Milosavljevic
f9c3b61884
arm-asm-testsuite.sh: Prefer current tcc as specified in $(TCC) 2021-01-06 02:18:14 +01:00
Danny Milosavljevic
f3912fafdd
arm-asm-testsuite.sh: Prefer cross-binutils' objdump 2021-01-06 02:14:49 +01:00
grischka
aeb8f427e2 tccgen: introduce TOK_NEG for unary minus
for floats (currently only).  On x86_64 uses built-in fp
constants (in libtcc1.c) to avoid multiple anonymous
instances.

Also: win32/i386: use __alloca for big struct stack store
- use new function int tok_alloc_const(const char*);
- change alloca86.S to preserve EDX

tccelf.c: fix a warning with 'roinf_use'
2021-01-06 01:44:22 +01:00
herman ten brugge
a5865fab22 text relocation for arm 2021-01-05 19:46:43 +01:00
herman ten brugge
81fec84012 disable nan test for clang 2021-01-05 19:44:06 +01:00
Danny Milosavljevic
77a6a9166d tests: Make arm-asm-testsuite.sh print the failed test cases. 2021-01-05 17:46:08 +00:00
Danny Milosavljevic
0c399306b8 tests: Call arm-asm-testsuite.sh on "asmtest" target. 2021-01-05 17:46:08 +00:00
CodeHz
425bd2a3db fix "invalid token at start of a preprocessor expression" 2021-01-05 17:46:08 +00:00
Christian Jullien
3873f95197 NetBSD: start arm support. WIP 2021-01-05 17:46:08 +00:00
Danny Milosavljevic
0754912ebd arm-asm: Add testsuite 2021-01-05 17:46:08 +00:00
Danny Milosavljevic
29f36a8953 arm-asm: Allow implicit offset 0 in input of asm_single_data_transfer_opcode 2021-01-05 17:46:08 +00:00
Danny Milosavljevic
483625065f arm-asm: Add ldrex, ldrexb, strex, strexb 2021-01-05 17:46:08 +00:00
Danny Milosavljevic
54ef167111 arm-asm: Implement branch to label 2021-01-05 17:46:08 +00:00
Michael Matz
29d8871d61 Implement proper floating point negation
Using "-0.0 - x" still isn't enough if x is a NaN, so bite the bullet
and implement sign-bit flipping via memory.  (It's usually not too bad,
the -0.0-x method also uses memory for the floating point constant).

This way is at least shorter than implementing a new top-level operation
for all backends (a negate) that would be unary.
2021-01-04 04:13:42 +01:00
herman ten brugge
4c9516941c Fix wine
After removing uint64_t from stddef.h the tcc_libm.h now needs to
include stdint.h
2021-01-03 20:12:34 +01:00
herman ten brugge
33d5a9fadb add arm64 relocs 2021-01-03 19:14:53 +01:00
Danny Milosavljevic
78d0f07e32
arm-asm: Improve immediate error message in asm_data_processing_opcode. 2021-01-03 15:54:19 +01:00
Danny Milosavljevic
a7205f738b
arm-asm: Support shift of 0 in asm_shift_opcode 2021-01-03 15:54:19 +01:00
Danny Milosavljevic
9539f51369
Makefile: Split arm64-asm from arm-asm 2021-01-03 15:49:17 +01:00
herman ten brugge
8712b4c9c1 Fix arm64 asm 2021-01-03 11:24:37 +01:00
Danny Milosavljevic
7f98aefddf
arm-asm: Implement subst_asm_operand 2021-01-03 02:34:12 +01:00
Danny Milosavljevic
9a460d3234
arm-asm: Implement asm_compute_constraints 2021-01-03 02:34:12 +01:00
Danny Milosavljevic
795d7d5ce6
arm-asm: Implement asm_gen_code 2021-01-03 02:34:12 +01:00
Danny Milosavljevic
d66c155239
arm-asm: Support bigger immediates for data processing instructions 2021-01-03 02:34:12 +01:00
Danny Milosavljevic
14b7973ab5
arm-asm: Add movw 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
c882d03673
arm-asm: Add movt 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
86cc9c587b
arm-asm: Raise error if asm_data_processing_opcode and asm_shift_opcode try to use PC for register-controlled shifts 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
79567004b4
arm-asm: Raise error if more than two operands are specified on mov, mvn, cmp, cmn, tst, teq 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
612d9d7ae6
arm-asm: Print a warning if asm_binary_opcode is used with SP as operand 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
67b402fda4
arm-asm: Raise an error if asm_binary_opcode is used with PC as operand 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
3a6f3e5f30
arm-asm: Add error case in asm_multiplication_opcode 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
e0cb5184f5
arm-asm: Warn if regset registers are not specified in ascending order 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
49365d563e
arm-asm: Support rotation for sxtb, sxth, uxtb, uxth 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
daaa88ce68
arm-asm: For data processing instructions, support shifts and rotations. 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
abef8f6ca7
arm-asm: Add lsl, lsr, asr, ror, rrx 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
b940d8edb2
arm-asm: Optimize gen_le32 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
b85c3e1595
arm-asm: Add b, bl, bx, blx 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
3b1f06c3b2
arm-asm: Add and, eor, sub, rsb, add, adc, sbc, rsc, tst, teq, cmp, cmn, orr, mov, bic, mvn 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
c7682dd9aa
arm-asm: Add ldr, ldrb, str, strb 2021-01-03 02:34:11 +01:00
Danny Milosavljevic
632b213756
arm-asm: Add stmda, ldmda, stm, ldm, stmia, ldmia, stmdb, ldmdb, stmib, ldmib 2021-01-03 02:34:10 +01:00
Danny Milosavljevic
82663d33bb
arm-asm: Add mul, mla, smull, umull, smlal, umlal 2021-01-03 02:34:10 +01:00
Danny Milosavljevic
c4e13c1ef9
arm-asm: Add clz, sxtb, sxth, uxtb, uxth 2021-01-03 02:34:10 +01:00
Danny Milosavljevic
c9e0c2a543
arm-asm: Add swi 2021-01-03 02:34:10 +01:00
Danny Milosavljevic
b495959e4b
arm-asm: Add push, pop
Also edited tcctok.h to not redefine push, pop
2021-01-03 02:34:10 +01:00
Danny Milosavljevic
c5428cd19c
arm-asm: Add parse_operand, Operand
tccpp: Allow '#' token to reach the assembler.
2021-01-03 02:34:10 +01:00
Danny Milosavljevic
a16678e9f3
arm-asm: Add wfe, wfi 2021-01-03 02:34:10 +01:00
Danny Milosavljevic
aaf052391d
arm-asm: Add nop 2021-01-03 02:34:10 +01:00
Danny Milosavljevic
9d302620c2
arm-asm: Remove asm_error 2021-01-03 02:34:10 +01:00
Danny Milosavljevic
b10824dcdc
arm-asm: Update copyright header 2021-01-03 02:34:10 +01:00
Danny Milosavljevic
f88ded6c2d
arm-asm: Implement asm_parse_regvar and asm_clobber 2021-01-03 02:34:10 +01:00
Danny Milosavljevic
4a6fb47b8d
arm-asm: Publish g, gen_le16, gen_le32 in tcc.h 2021-01-03 02:34:10 +01:00
herman ten brugge
3221cc4a5a Align next section after gnu_ro to pagesize
To allow remapping the ro section the next section must start
on a new page.
2021-01-02 15:17:25 +01:00
Christian Jullien
b147a37c23 Remove useless [u]intN_t definitions from stddef.h 2021-01-02 11:23:26 +01:00
Christian Jullien
c9fe8fe470 Yet another int64_t/uint64_t definition fix. For wine this time. 2021-01-02 05:58:46 +01:00
herman ten brugge
2633c30fb4 riscv64 update
implement load/store to constant address
use VT_LLONG instead of VT_PTR in register passing
fix bound checking problem with small structs
enable riscv tests in tests/tcctest.c and tests/tests2/119_random_stuff.c
2021-01-01 20:36:57 +01:00
Christian Jullien
9a2a05ba1e *BSD: fix extra #endif 2021-01-01 16:01:03 +01:00
Christian Jullien
33257c6439 *BSD: protect against incompatible redefinitions of int64_t/uint64_t. 2021-01-01 08:50:13 +01:00
herman ten brugge
8db839cc85 FreeBSD32 struct return 2020-12-31 06:48:14 +01:00
herman ten brugge
9d49883895 update clang warning 2020-12-31 06:39:56 +01:00
grischka
ea82d0826d tccpp: cleanup target-os defines
moved target_machine defines to the <target>-gen.c files.

Also:
- c2str.c moved into conftest.c
- tccdefs.h ; defined(__TINYC__) && !defined(_LOCORE) removed
  (in tinycc __TINYC__ is always defined and _LO... is never.)
- stddef.h : too many #ifdefs, removed
- tccgen.c:stabs: support win32 long doubles aka doubles.
- win32: math.h/tcc_libm.h: fix pointer mismatch in modfl
- tccpp.c: increment include_stack_ptr after the file was
  actually found otherwise it would print
  "in file included from <itself>: file not found..."
2020-12-31 02:03:31 +01:00
Michael Matz
d784b28877 No need for sm_table.size entry
the sh_size input member is reliable, we don't need to duplicate
it in the section mapping info.
2020-12-31 01:21:52 +01:00
Michael Matz
b117088a91 Explain some reloc hackery
just changes a comment; it's not specific to __dso_handle, but general
to all hidden defined symbols for shared libraries.
2020-12-31 00:54:00 +01:00
Michael Matz
60eac659d4 fix cross compiler compilation
{l,}bounds_section is only conditionally defined.
2020-12-31 00:16:23 +01:00
herman ten brugge
cf10c1db66 Fix clang warnings 2020-12-30 19:12:05 +01:00
herman ten brugge
85b6efbf0c Real fix include SHT_NOTE sections everywhere
Thinko in last commit
2020-12-30 18:23:43 +01:00
herman ten brugge
766bd82032 Fix include SHT_NOTE sections everywhere 2020-12-30 16:24:15 +01:00
herman ten brugge
0821940e26 text relocation for netbsd
netbsd does not allow text relocations in text segment.

tcc.h:
- Add data_ro_section
- Fix typo rela.plt

tccelf.c:
- Add data_ro_section
- Make bounds_section/lbounds_section rw
- Add GNU_RELRO section for data_ro_section/bounds_section/lbounds_section
- Fix relocation for __dso_handle in atexit()

tccgen.c:
- Use data_ro_section

x86_64-gen.c:
- Use R_X86_64_PC32 instead of R_X86_64_64 for bounds checking

tests/Makefile, tests/tests2/Makefile
- Enable dll tests for netbsd
2020-12-30 14:08:06 +01:00
Christian Jullien
c13c434383 Fix warnings detected by clang when compiling c2str. 2020-12-30 08:57:30 +01:00
Michael Matz
cc40305a12 Fix errors with parallel make
seen when doing 'make -j i386-tcc tcc', as explained in the comment.
2020-12-25 02:10:43 +01:00
Christian Jullien
16ed67537c NetBSD: longjmp(jmp_buf, 0) is not supported. 2020-12-24 09:29:25 +01:00
Christian Jullien
b9db7c90ee NetBSD: arm64 prevent use of __asm. 2020-12-24 07:31:52 +01:00
Michael Matz
1032e7175a ELF: include SHT_NOTE sections everywhere
... not just on the BSDs.  Sometimes e.g. .note.ABI-tag is allocated
and other sections might contain relocations referring to symbols in
them.  TCC doesn't do any special processing to them, like merging
or somesuch, it just pastes them all together in normal link-editing
behaviour.

(Seen on a recent openSUSE with glibc 2.32, when the crt1.o file
contains debug information)
2020-12-24 07:01:04 +01:00
Christian Jullien
b56099aeb4 NetBSD: arm64 fix int64_t/uint64_t definitions. 2020-12-24 06:50:48 +01:00
Christian Jullien
63e29113ab NetBSD: arm64 requires at least gcc 4.1 to work 2020-12-23 20:52:25 +01:00
Christian Jullien
ba61c7bb37 NetBSD: arm64 is curiously detected as evbarm. Struct uc_mcontext is once again different. 2020-12-23 20:08:26 +01:00
herman ten brugge
f7d2d04d96 Fix include/tccdefs.h
Remove __amd64__ for FreeBD (32 bits version did not work any more)
Add __APPLE__ at HAVE MALLOC_REDIR so bound checking works on apple
2020-12-22 18:53:29 +01:00
herman ten brugge
0352c41a07 add R_ARM_GOT_PREL for clang 2020-12-22 14:31:09 +01:00
grischka
9f6b65230a include/tccdefs.h: moved and use it
tcc_define_symbol(): now only for -D on command line
include/tccdefs.h: converted to strings and compiled into
the tcc executable.  Can be disabled with
    ./configure --config-predefs=no
In this case include/tccdefs.h is loaded at runtime.  This is
default for other build-methods (build-tcc.bat) also (to avoid
some complexity).

Also:
- lib/Makefile: fix typo
- tcc.h : avoid _strto(u)i64 (for TCC on WIN98/2K)
- tccpp.h:cstr_printf() : workaround incompatible vsnprintf's
  (generally faster too)
2020-12-22 11:06:19 +01:00
herman ten brugge
8f8abcc756 more bsd updates
This implements support for FreeBSD on aarch64
This partial implements support on FreeBSD(32). This still needs fixing
i386_gen.c because small structures on this target are passed in registers.

Add aligned 16 to __int128_t for FreeBSD
Support __i386__ on FreeBSD/NetBSD
Fix testcase 115 on FreeBSD/NetBSD
Disable testcase 116 on *BSD* because TLS_FUNC/TLS_VAR not set in bcheck.c
Remove FreeBSD/FreeBSD_kernel code from tccelf.c
2020-12-22 07:02:47 +01:00
Christian Jullien
888f4fd982 FreeBSD (aarch64): fix relocation error. 2020-12-22 05:52:45 +01:00
Christian Jullien
6cc87629b4 NetBSD: define __amd64__ which is sometimes used in headers. 2020-12-20 14:19:55 +01:00
Christian Jullien
a493fbb1fa *BSD: mention all BSD ports in README. 2020-12-20 10:50:07 +01:00
Christian Jullien
d4a4ee798b FreeBSD: Fix multiple ctype inline definitions 2020-12-20 09:45:16 +01:00
Christian Jullien
ac470a49d5 *BSD: Add few __builtin_ math missing definitions. 2020-12-20 07:26:04 +01:00
herman ten brugge
7eea5306e9 rename testcase 106 2020-12-19 21:02:44 +01:00
herman ten brugge
7f898abb82 bsd update
Fix crtbegin/crtend
Use dlsym on all bsd targets
Check .eh_frame on all bsd targets
Disable test3 on FreeBSD and NetBSD and use test1 instead because dlsym not working (WIP)
Disable dlltest and 113_btdll on NetBSD because text relocations are not allowed
Disable 115_bound_setjmp on NetBSD because longjmp is renamed into __longjmp14
2020-12-19 20:55:52 +01:00
herman ten brugge
a87dee588b dlltest_arm
This fixes the dlltest_arm on arm(32)
2020-12-19 20:33:36 +01:00
herman ten brugge
50b4f320dc lazy binding
Currently tcc does not use lazy binding. It puts all relocations in the RELX
section and solve them all at startup.
This was not working on bsd.

tcc.h:
- New RELPLT_SECTION_FMT for plt relocations
- New entry relocplt in struct Section

tccelf.c:
- put_elf_reloca: put R_JMP_SLOT in relocplt section
- build_got_entries*: Use two passes because R_JMP_SLOT and R_GLOB_DAT
                      can not be intermixed on some targets (arm, arm64)
- layout_sections: Calculate correct size relocplt section for DT_ values.
                   Make sure relocplt is last
- fill_dynamic: Add DT_ values when got is filled
                move DT_VERSYM because dynamic linker cannot handle it standone
- Add note section for NetBSD

arm-link.c/arm64-link.c/i386-link.c/riscv64-link.c/x86_64-link.c:
- fill got table with pointer to plt section or symbol value in case
  of TCC_OUTPUT_MEMORY

arm-link.c/arm64-link.c:
- fix offset first plt entry

i386-link.c/x86_64-link.c:
- use correct reloc entry
- use relofs - sizeof (ElfW_Rel) because the reloc is already done

lib/bcheck.c:
- no __libc_freeres on FreeBSD and NetBSD

tests/Makefile:
- Add -fno-stack-protector for OpenBSD

tests/tests2/Makefile:
- disable 106_pthread/114_bound_signal
2020-12-18 15:24:32 +01:00
grischka
e2e62fcb8b replace native platform macros in the compiler
- The compiler should not use these
- However tccrun.c & libtcc1.a files should use these
Also:
- use s1->loaded_dlls for loaded dlls instead of dlopens
- alpine musl: fully supported now and tested
- ./configure ...
   --config-backtrace=no : disable backtraces
   --config-bcheck=no : disable bcheck
- tests:dlltest: enable by default
- tccrun.c : simplify mmaps
- __builtin_alloca : always use asm-alias (instead of #define)
- tccpe.c : use write32le
2020-12-17 12:39:16 +01:00
Christian Jullien
02f61d5b49 riscv64: mention this supported cpu in README. 2020-12-17 09:10:00 +01:00
Christian Jullien
d5519c929c OpenBSD: mention this port on README 2020-12-17 06:22:10 +01:00
herman ten brugge
6eef0e35b4 OpenBSD: testcases
Fix all testcases for openbsd except dlltest.

Remember dlopen calls and use them to fix openbsd dlsym problem
Use crtbeginS.o/crtendS.o for DLL for bsd
Do not include -ldl for __NetBSD__
Redirect malloc, realloc, ..., free for bsd
Align stack in tests/asm-c-connect-*.c for x86_64
Remove -B in tests/pp/Makefile (not supported on bsd)
2020-12-16 17:52:59 +01:00
Christian Jullien
f48a9ed001 FreeBSD (on arm64): partial support, only -run works - WIP 2020-12-13 11:08:44 +01:00
Christian Jullien
eab324a7cf NetBSD (on arm64): reorder cpu detection to detect aarch64 target when cpu is arm64 2020-12-13 10:22:15 +01:00
Christian Jullien
c32cfc1113 NetBSD: predefine __ELF__ macro which is tested by some standard headers 2020-12-13 07:24:01 +01:00
Christian Jullien
f233cb182c NetBSD: reintroduce NetBSD support. Currently, -run works but executable has an incorrect format. 2020-12-11 14:26:26 +01:00
grischka
8ff705554d tcc_enter/exit_state(): do not use!
tcc_enter/exit_state() are meant exclusively to protect
the tcc_compile() and its sub-functions in tccpp.c,
tccgen.c, tccasm.c and xxx-gen.c.

Other files that are part of libtcc simply must not use global
variables.

- riscv64/last_hi: move to TCCState
  from 72250bece2

- tccrun.c: Using a fixed address would not work anyway
  ("tcc -run tcc.c -run ..." for example)
  from baacb0f52a

- tests/Makefile: support for a platform doesn't make sense if
  it doesn't pass our basic tests.
  from 591feda103
Also:
- tccgen: cleanup "duplicate member" (only 2 passes,
  avoids additional TokenSym field)
  from 170be79a42
2020-12-08 19:57:57 +01:00
Christian Jullien
a06fef3b11 FreeBSD: little better support that targets FreeBSD 12.2 on amd64 but still not working - WIP 2020-12-08 09:13:29 +01:00
Christian Jullien
f9c580b8a0 FreeBSD: start to reintroduce support - WIP 2020-12-08 06:55:50 +01:00
herman ten brugge
591feda103 OpenBSD: disable some tests 2020-12-07 12:06:17 +01:00
herman ten brugge
72250bece2 riscv64 relocation fix 2020-12-07 11:36:54 +01:00
herman ten brugge
baacb0f52a OpenBSD: runtime fixes
After this commit we can compile and run code with some limitations.
- The dlsym function is broken so this makes -run and bound checking
  not work all the time. Make -k test does work for most code.
- You have to do:
    ln -s /usr/lib/libN.so.x.y /usr/lib/libN.so
  for all .so files in /usr/lib.
  OpenBSD uses opendir/readdir to find the correct so file. This is
  not the way other platforms do this.
  Also the .a versions do not have all symbols that are present in the .so
  files.

tcc.h:
- Use different dynamic loader

elf.h:
- Add SHT_X86_64_UNWIND

tccelf.c:
- Do not use -dl
- Add required NOTE section
- Add extra dynamic tags
- Allow SHT_X86_64_UNWIND/SHT_NOTE in tcc_load_object_file

tccrun.c:
- Uses MAP_FIXED because without the offset between exec and data section
  becomes too big for x86_64

lib/bcheck.c:
- Do not use __libc_freeres

tests/tcctest.c:
- aligned_function also disabled for __GNUC__ == 4
2020-12-07 08:27:10 +01:00
Christian Jullien
19d287aae3 OpenBSD: fix typo in _ANSI_LIBRARY defined symbol 2020-12-07 07:57:01 +01:00
Christian Jullien
a3d5e4aa43 OpenBSD: define more internal symbols to support tcc on OpenBSD. 2020-12-07 07:15:56 +01:00
herman ten brugge
170be79a42 duplicate member
Check duplicate struct/union member names

tcc.h: Add cnt field in TokenSym

tccgen.c: New function check_fields to find duplicate member names.

This avoids quadratic behavior and can be used for large structs.
2020-12-03 07:53:44 +01:00
Christian Jullien
6f2659c230 OpenBSD: SYS_gettid syscall is named SYS_getthrid - WIP 2020-12-02 08:05:34 +01:00
Christian Jullien
38dea90b2f OpenBSD: workaround missing SYS_gettid - WIP 2020-11-29 08:54:55 +01:00
Christian Jullien
dfe031caa6 OpenBSD: Fix crt startup names - WIP 2020-11-29 08:47:27 +01:00
Christian Jullien
4e12c2a6dc OpenBSD: improve partial support for x86_64 - WIP 2020-11-27 11:24:19 +01:00
grischka
cf8d9cf072 win64: fix pe_isafunc()
- tccpe.c: commit "tidy support for helper function" created
  STT_NOTYPE symbols and hence relied on ad-hoc detection which
  didn't work for x86_64 (as reported by Christian Jullien)

- tccgen.c: However to be more safe the helper symbols are
  now made STT_FUNC anyway (via new VT_ASM_FUNC).

Also:
- tcc.h: minor reorder
- riscv64-*, arm64-*, tccmacho.c: avoid some gcc format-warnings
  (mingw-gcc complains about "%llx" being "unknown conversion",
  although it does work since Vista or so)
2020-11-26 16:11:17 +01:00
Tyge Løvset
13a18906ef win32 tcc_libm.h: Implemented overrides for msvcrt.dll's frexp(), ldexp(), and fabs() with speedups 4.5X, 7.3X and 6.3X correspondingly.
This is the last commit on this for now.
2020-11-25 14:29:42 +01:00
grischka
4a42b0d95e tidy support for helper function such as memmove
tcc.h, tccgen.c: Introduce Sym *external_helper_sym(int v);
  to create an external reference with no specific type. This
  avoids type conflicts if the symbol is used from C too.
the other files: use it.
2020-11-24 11:47:02 +01:00
Tyge Løvset
2f78f54924 win32 libm: Final optimizations and added nan*() function. 2020-11-23 20:42:36 +01:00
Arthur Williams
3709f8de14 Treat func pointers with different return types as not compatible
Tcc considered function ptrs with different return types to be
compatible which disallowed some otherwise valid operations like:
`_Generic(foo, int(*)():0, void(*)(void):1)`
which would fail to compile with a error message of "type match twice"

This changed also required longjump's return type to be void and
munmap's to be int to be compatible with standard headers.
2020-11-22 16:30:34 -06:00
Tyge Løvset
3b1a42e734 Cleanup and minor fixes in win32/tcc/tcc_libm.h: truncf(), cbrtf(), exp2f(), log2f(), scalbln*() 2020-11-21 14:45:35 +01:00
Tyge Løvset
b11144d69c Overhauled WIN32 math and added missing functions:
1) Cleanup: moved function implementations from win32/include/math.h to win32/include/tcc/tcc_libm.h
2) Added missing math functions: MUSL: asinh(), acosh(), atanh(), scalbn(). My impl: log1p(), expm1(), ilogb(), scalbln(), nexttoward()
 - now only a few are missing: remquo(), remainder(), fma(), nan(), erf(), erfc(), nearbyint().
3) Added/defined all missing *f() and *l() math functions.
4) Added functions have short but accurate/fast implementations.
5) Added <tgmath.h> for all platforms. (not too useful, IMO, but is C99 standard).
2020-11-20 23:34:35 +01:00
Wirtos_new
82611f5e6d Fix char limits
By the standard CHAR_MIN and CHAR_MAX should be 0 and UCHAR_MAX respectively when char implementation is unsigned ( -fno-signed-char)
2020-11-17 09:06:48 +02:00
Tyge Løvset
1073b379c8 WIN32/64 only: Added C99 math functions: tgamma(), tgammaf(), lgamma(), lgammaf(), cbrt(), cbrtf(), log2(), log2f(), exp2(), exp2f().
The gamma() functions are accurate to 13 digits over the full range. Returns INFINITY / NAN identical to other compiler's math libs.

#include <stdio.h>
#include <math.h>

int main() {
  double x;
  for (x = -7.0; x <= 520.0; x += 1.0) {
    printf("tgamma/lgamma %6.3f: %20.13g  %20.13g\n", x/3, tgamma(x/3.0), lgamma(x/3.0));
  }
  printf("tgamma/lgamma %g: %20.13g  %20.13g\n", 0.00000234, tgamma(0.00000234), lgamma(0.00000234));
  printf("log2, exp2, cbrt, cbrt: %.15g %.15g %.15g %.15g\n", log2(1024), exp2(10), cbrt(-10), cbrt(10));
}
2020-11-14 00:02:58 +01:00
herman ten brugge
08d8015750 Fix fork problem 114_bound_signal
There is a race condition in old libc in fork().
The result was that 'end' was sometimes printed twice.

This did not happen with glibc-2.32.
2020-11-10 10:08:30 +01:00
herman ten brugge
54b4aa3cd6 Disable signals in bcheck.c pthread_create
glibc-2.32 contains new code to prevent a race conditions with signals
in pthread_create.
2020-11-09 10:57:14 +01:00
grischka
8b69059f66 three small fixes & three reverts
- tcc.h: msvc doesn't grok __func__ (reverts previous commit)

- tccgen.c: fortify tcc against bogus code:
  - n[sizeof({3;})]; // statement expression outside of function
  - f(){"123"4}; // tokens with values following each other
  (also, add "type defaults to int" warning for variables)

- tccpe.c: removed a check that caused BSS symbols not to be
  exported.  Whatever that check was meant to prevent.

- win32/build-tcc.bat: cmd.exe sometimes doesn't grok '-' in labels

- Revert "libtcc: no need to undef"
  This reverts commit 2b7aa2a1e1.
- Revert "tcc.h libtcc.c: remove unused defines"
  This reverts commit 985d963745.

The point of these "unused defines" is to be unused,  that is
to remind people not to use malloc but please to "use_tcc_malloc",
instead.
2020-11-02 18:08:56 +01:00
Kyryl Melekhin
2b7aa2a1e1 libtcc: no need to undef 2020-11-01 15:51:50 +00:00
Kyryl Melekhin
985d963745 tcc.h libtcc.c: remove unused defines
pretty sure that functions with use_* do not exist
and attempts to use the macros will fail to link
I could rename them to be more up to date like tcc_malloc,
but to me overloading the std calls with macros is
probably taking away control from the programmer,
so for the best is to just get rid of them.
2020-11-01 15:24:45 +00:00
John Scott
53587ee415
tcc_internal_error: print function with __func__.
Though __func__ was introduced in C99, this is
preferable to __FUNCTION__, an obsolete GCC extension.
Found with gcc -Wpedantic.
2020-10-18 17:54:01 -04:00
John Scott
558c6f56e2
tcc_mallocz: clear with memset only if nonzero size
Even if non-NULL, dereferencing the pointer from malloc(0)
or passing it to memset() may invoke undefined behavior.
2020-10-16 21:20:33 -04:00
grischka
72b520e709 tccgen: flex arrays etc.
Fixes potential writes past the allocated space with mostly
illegal flex array initializers. (60_errors_and_warnings.c
:test_var_array)

In exchange suspicious precautions such as section_reserve
or checks with sec->data_allocated were removed.  (There is
an hard check 'init_assert()' for now but it's meant to be
just temporary)

Also, instead of filling holes, always memset(0) structures
& arrays on stack.  Sometimes more efficient, sometimes isn't.
At least we can omit putting null initializers.

About array range inititializers:  Reparsing tokens has a
small problem with sideeffects, for example

   int c = 0, dd[] = { [0 ... 1] = ++c, [2 ... 3] = ++c };

Also, instead of 'squeeze_multi_relocs()', delete pre-existing
relocations in advance. This works even if secondary initializers
don't even have relocations, as with
    [0 ... 7] = &stuff,
    [4] = NULL

Also, in tcc.h: new macro "tcc_internal_error()"
2020-10-03 18:12:46 +02:00
grischka
40395511d7 Revert "function pointer compare"
Always fine to try out things but not everything must be shown
to the public. ;)

Also, AFAIK pointers must compare equal only if derived directly
from each other (for example by cast to void* and back).

This reverts commit 8f9bf3f223.
2020-10-03 17:40:22 +02:00
grischka
cdc3df949b tcc -bench: show text/data/bss binary output sizes 2020-10-02 19:50:45 +02:00
herman ten brugge
ae1796fc34 Fix testcase 114 for arm and apple
Arm has a problem with tls after a fork. The pthread_key_create seems to
be forgotten?

Apple has a problem with the exit(0) code in do_fork(). An IO mutex
is still held after a fork().
2020-10-02 17:50:31 +02:00
Michael Matz
78da4586a0 Fix tests2/120_alias.c on macos
While MacOS doesn't natively support the alias attribute, let's support
it with TCC anyway.  This means we need to make a decision if the
string in the alias attribute is decorated or not due to the implicit
underscore on MacOS.  To make life easier we decide that it's the C name,
i.e. without underscore, and so TCC needs to emit alias names with
underscore handling.

Irrespective of that the test case needs to deal with the underscore
itself for __asm__ renaming which is always requiring the assembler name.
2020-10-01 18:03:56 +02:00
herman ten brugge
0da93838c1 Init range wth symbols
The init range with symbols did only init the first value.
The relocation for all other symbols was missing.
Also see testcase.

tccgen.c:
- New function get_init_string
- Use macro processing in decl_designator for each init string
- Use get_init_string in decl_initializer_alloc

tccelf.c:
- Fix insertion sort in squeeze_multi_relocs

tests/tests2/90_struct-init.c:
- Add test case test_init_ranges
2020-10-01 17:50:20 +02:00
herman ten brugge
afc0917f88 Bound checking fixes
tccgen.c:
- Fix 'tcc -b conftest.s'
- Add offset during bound checking for struct return

lib/bcheck.c:
- Check overlap when reusing vla/alloca

arm-gen.c:
arm64-gen.c:
riscv64-gen.c:
lib/alloca86-bt.S:
- add space for vla/alloca during bound checking

tests/tests2/Makefile:
tests/tests2/121_struct_return:
tests/tests2/122_vla_reuse:
- New test cases with bound checking enabled to test vla and struct return
2020-10-01 17:09:09 +02:00
Michael Matz
352e1d0fc4 Reinstate attribute alias handling
commit 2a0167a merged alias and asm symbol renaming, but broke
semantics of aliases, see testcase.  Basically the difference between
the two is that an asm rename doesn't generate a new symbol, i.e. with

  int foo __asm__("bar");

all source reference to 'foo' will be to 'bar', nothing of the name
'foo' will remain in the object file, and for instance reference to
'foo' from other compilation units won't be resolved to this one.

Aliases OTOH create an additional symbol.  With:

  void target (void) { return; }
  void afunc (void) __attribute__((alias("target")));

reference to 'afunc' will remain 'afunc' in the object file.  It will
generate two symbols, 'afunc' and 'target' referring to the same entity.
This difference matters if other compilation units make references to
'afunc'.

A side requirement of this is that for alias to work that the target
symbol needs to be defined in the same unit.  For TCC we even require a
stricter variant: it must be defined before the alias is created.

Now, with this I merely re-instated the old flow of events before above
commit.  It didn't seem useful anymore to place both names in the
asm_label member of attributes, and the asm_label member of Sym now
again only needs the hold the __asm__ rename.

It also follows that tcc_predefs.h can't make use of attribute alias to
e.g. map __builtin_memcpy to __bound_memcpy (simply because the latter
isn't defined in all units), but rather must use __asm__ renaming, which
in turn means that the underscore handling needs to be done by hand.
2020-09-30 17:46:01 +02:00
herman ten brugge
727e24cb0a Add typedef debug info
tccgen.c:
- In tcc_get_debug_info mask VT_STORAGE instead of VT_EXTERN | VT_STATIC
- New function tcc_debug_typedef
- Call tcc_debug_typedef in decl0
2020-09-27 11:13:37 +02:00
herman ten brugge
8fd7a384e2 Fix bitfields init : tiny solution
tccgen.c: Check struct/union size for bitfield.
tests/tcctest.c: Add test code.
2020-09-25 12:23:48 +02:00
herman ten brugge
89ea62481d clang7 does not support zero sized structs
This happens with aarch64 on raspberry pi.
2020-09-21 15:55:58 +02:00
herman ten brugge
8f9bf3f223 function pointer compare
tccelf.c:
- Check if symbol is in data section and UNDEF. Then generate new
  relocation and let dynamic linker solve it.

tests/tests2/42_function_pointer.c:
- Add new test code
2020-09-21 09:18:48 +02:00
Christian Jullien
ffac4e7688 Herman proposed patch seems to fix clang issue on x64 Debian 2020-09-19 08:04:20 +02:00
grischka
8cb3e5368f bitfields init : tiny solution
This replaces commit 5c6356ff8e,
except the tests.
2020-09-18 23:31:34 +02:00
herman ten brugge
5c6356ff8e default-initialization of bitfields
The code:

struct bf_SS {unsigned int bit:1,bits31:31; };
void func(void) {
  struct bf_SS bf_finit = { .bit = 1 };
}

will not init bits31 to 0.

tccgen.c:
- check_bf: New function to check if bitfield is present in struct/union
- decl_initializer: Call check_bf and set value to 0 is bitfield found

tests/tcctest.c:
- Add struct bitfield test code
2020-09-18 19:20:57 +02:00
Christian Jullien
6d819d7267 Indentation was missing after empty string check was added by wanjochan. 2020-09-18 06:39:30 +02:00
wanjochan
bea7dcde86 check strlen(TCC_LIBTCC1) before tcc_add_support(s1, TCC_LIBTCC1) 2020-09-18 06:57:56 +08:00
grischka
aed5cd0ce9 revert 'no-libtcc1' feature
from 43ae350390
and a3578379fb

Sorry, but this feature appears to be rather a personal
experiment than generically interesting for other people.
Also those "other people" always have some interest in
TCC staying simple.

One can still avoid the startup code from libtcc1.a simply
by providing __start explicitly.

While at it: Tidy tccpe.c:pe_add_runtime(), somewhat.
2020-09-17 20:57:21 +02:00
grischka
4cd6298f9d libtcc1.c: cleanup fp2ull
- replace '>>' by '<<' in __fixunsxfdi (typo)
- replace 'long' by 'long long' (long may be 32 bits)
- return an overflow result more similar to GCC
2020-09-17 20:25:31 +02:00
Kyryl Melekhin
55b4754e84 Revert "add tests for float conversions to u64"
Because test's are not applicable in this case.

This reverts commit a5e714abec.
2020-09-17 07:12:49 +00:00
herman ten brugge
c9bbd4e707 Allow strings in __builtin_constant_p
tccgen.c:
- Fix handling __builtin_constant_p

tests/bug.c:
- Remove tst3

tests/tcctest.c:
- Add new tests for __builtin_constant_p
2020-09-17 09:11:10 +02:00
herman ten brugge
4a16bebfab Struct va_arg fix
lib/va_list.c:
- Handle struct {double, double} correctly

arm64-gen.c:
riscv64-gen.c:
x86_64-gen.c:
- Allow zero sized structs to work with va_arg

tcctest.c:
- Add new va_arg test code

test/bug.c:
- Remove tst2 va_arg test
2020-09-17 08:42:28 +02:00
herman ten brugge
757a97466f Fix testcase 114 for macos
lib/bt-exe.c:
- call __bound_init before sigset_exception_handler because sigaction
  is redirected.

tests/tests2/Makefile:
- run testcase 114 on macos again
2020-09-17 08:22:53 +02:00
Christian Jullien
13c66526ed Fix wanjochan commit 'when tcc1 omit: use main()' when tcc is bootstrapped by tcc on Windows. Variable must be NULL initialized 2020-09-17 06:52:39 +02:00
Christian Jullien
15182d7fdd Don't mix code and declaration 2020-09-17 06:51:59 +02:00
wanjochan
a3578379fb when tcc1 omit: use main() directly 2020-09-17 10:26:16 +08:00
wanjochan
7eebf614dc tcc c-tyle-compliance: space between if and ( 2020-09-17 06:54:13 +08:00
wanjochan
89935229a7 tcc_add_support(): void return for win 2020-09-17 00:53:50 +08:00
wanjochan
43ae350390 tcc_add_support(): skip when filename is empty 2020-09-17 00:47:32 +08:00
wanjochan
55eafa66b7 test 114: skip bcheck for osx (tcc -run not support fork with -b) 2020-09-17 00:43:19 +08:00
herman ten brugge
d55e586bc6 Fix boundschecking fork for macos/SELINUX
lib/bcheck.c:
- Use INIT_SEM for child process fork on macos

tests/tests2/Makefile:
- tcc -run does not work for fork due to SHARED mmap
2020-09-14 19:31:56 +02:00
herman ten brugge
61c0c852b5 Update boundschecking for fork
bcheck.c:
- Fix fork function.
- Move use_sem
- Fix bound_alloc_error text

tests/tests2/114_bound_signal.c:
- Add test for fork
2020-09-14 08:24:01 +02:00
Pursuer2
8878c29c5d misplaced parenthese around definition of CONFIG_TCC_BCHECK 2020-09-12 07:09:18 +02:00
Kyryl Melekhin
a5e714abec add tests for float conversions to u64
Note:
I removed the test that used sin()
function because it makes no sense
to use that there and besides I could
not get the test to work because
sin requires -lm linked but for some reason
make does not compile with -lm and
I get errors like undefined symbol sin.
Coerce function should do the same thing
for the purposes of that test.
2020-09-11 09:18:58 +00:00
Kyryl Melekhin
618ba55a81 fix float to u64 intrinsics
reverts commit
310e3b428c
(more info there)

now functions check for
sign bit in float.

now hopefully this patch will
cover entirety of areas it might affect
2020-09-10 17:35:36 +00:00
Christian Jullien
60c1f70bb9 Revert commit 55f8963dfa from wanjochan until better tested on all platforms 2020-09-10 05:49:15 +02:00
Kyryl Melekhin
310e3b428c (bug caused by tcc intristics)
reproduce bug:
$ ./configure --cc=gcc
$ make
$ make install
(OK)
run a test:

extern int printf(const char *str, ...);
int main()
{
        int t2 = (int)(-1.847759065f * 4096);
        printf("%d\n", t2);
}

$ tcc test.c
$ ./a.out
$ -7568
(OK)

(self compiled now)
$ ./configure --cc=tcc
$ make
$ make install
(OK)

$ tcc test.c
$ ./a.out
$ 7568
(WRONG!!!)

why:
gcc does not have intristics for
uint to long double conversion
therefore it does cast implicitly, so
the sign bit is preserved, but this does
not happen when __fixunsxfdi is called
because tcc was bootstrapped.

solution:
force cast to int64 and preserve the
sign bit.

side effects:
not found.
2020-09-08 22:12:01 +00:00
wanjochan
55f8963dfa ignore symbol main for .dylib; skip libtcc1 for tccrun mode; 2020-09-08 22:05:00 +08:00
herman ten brugge
853a498f2c Fix boundschecking for signal/sigaction/fork
The BOUNDS_CHECKING_ON/BOUNDS_CHECKING_OFF is not working for
signal/sigaction/fork. The reason is that the code stops bound checking
for the whole application. This result in wrong handling of
__bound_local_new/__bound_local_delete and malloc/calloc/realloc/free.
Consider the following code:

void tst(int n) {
  int i, arr[n];
  for (i = 0; i < n; i++) arr[i] = 0;
}

void *some_thread(void *dummy) {
  while (running) { tst(10); tst(20); }
}

void signal_handler(int sig) { ... }

When the signal handler is called the some_thread code can be interrupted when
is just registered the arr[10] data. When the signal handler is leaved the
arr[10] is still registered and did not see the call to deregister arr[10] and
then register arr[20]. The code resumes when tst(20) is running. This results
in a bound checking error when i >= 10.

To solve the above problem I changed the bound checking code to use
tls (thread local storage) for the no_checking variable.
This also makes it now possible to redirect signal/sigaction/fork code
through the bound checking library and disable checking when a signal is
running and to correct the bounds_sem for the fork child process.
The BOUNDS_CHECKING_ON/BOUNDS_CHECKING_OFF is not needed any more for
signal/sigaction/fork. In fact I could remove them from all my applications.

The use of the tls function code slows down the code by about 10%.
So if the slowdown due to bound checking was 5. It is now 5.5 times slower.

For x86_64/i386 I also allowed to use __thread variable in bcheck.c when
compiled with gcc with:
make x86_64-libtcc1-usegcc=yes
make i386-libtcc1-usegcc=yes
This makes code run faster due to use of gcc and __thread variable.
With the __thread variable there is no 10% slowdown.
For other targets this does not work because stabs is not supported.

Changes:

lib/bcheck.c:
- Add TRY_SEM
- Add HAVE_SIGNAL/HAVE_SIGACTION/HAVE_FORK/HAVE_TLS_FUNC/HAVE_TLS_VAR
  - HAVE_SIGNAL: redirect signal() call if set.
  - HAVE_SIGACTION: redirect sigaction() call if set.
  - HAVE_FORK: redirect fork() call if set.
  - HAVE_TLS_FUNC: If target has tls function calls.
  - HAVE_TLS_VAR: If target has __thread tls support.
- Replace all no_checking refecrences to NO_CHECKING_SET/NO_CHECKING_GET macros

tcc-doc.texi:
- Remove examples for signal/sigaction/fork code.
- Add some explanation for signal/sigaction/fork code.
- Add documentaion for __bounds_checking().

tccelf.c:
- Add support for SHF_TLS

tests/tests2/114_bound_signal.c:
- Remove BOUNDS_CHECKING_ON/BOUNDS_CHECKING_OFF
- Add code to trigger failure when tls is not working.

x86_64-link.c:
- Add support for R_X86_64_TLSGD/R_X86_64_TLSLD/R_X86_64_DTPOFF32/R_X86_64_TPOFF32

i386-link.c:
- Add support for R_386_TLS_GD/R_386_TLS_LDM/R_386_TLS_LDO_32/R_386_TLS_LE
2020-09-08 14:31:58 +02:00
grischka
53d815b8a0 win32/tccpe: use full dll-path with -run
This allows for example this scenario:

- A dll to be linked with is specified in file.c, where file.c
  and the dll exist in the same directory:
    #pragma comment(lib, "txml")
    #pragma comment(option, "-L{f}")

- tcc is called to run file.c from other, varying directories:
    $ tcc -run some/dir/file.c <args...>

Note that tcc replaces {f} by the currently compiled file's
directory ('some/dir' in this example).

Also:
- tccgen.c: fix last commit for gen_cast.
2020-08-21 22:47:56 +02:00
grischka
d746e32349 tests2: rework 117..119 to follow our conventions
Please respect some conventions:

- tests2 filenames don't end with '..._test'

- tests2 tests are meant to produce some output

- the output should be somehow informative, not just
  "error" or "dummy". Because other people would want to
  know where it fails if it does.

- tests2 tests should work with both GCC and TCC, except
  if there are specifc reasons (like testing tcc-only
  feature such as bounds checking)

- tests2 tests should never crash or abort.  Because that
  would cause gui dialogs to pop up on windows, and because
  other people would not know where it fails if it does.

- tests2 tests should be somehow specific, in general.
  (rather than just collections of random stuff)

- in general, do not use 'long' if you mean 'larger than int'
  Because it isn't on many platforms.

- use four (4) spaces for block indention.  Do not insert
  tab characters in files if possible.

Also:
- tccgen.c:gen_cast() simplify last fix.
2020-08-21 21:44:11 +02:00
grischka
f9870f7860 bcheck: remove static (compile-time) control
Providing both run-time and compile-time control for bounds
checking as an user interface appears unnecessary and confusing.

Also:
- replace 'bound_...' by 'bounds_...' for consistency
- tcc-doc: put related info into one place and cleanup

The __bounds_checking(x) function is still missing explanation.
(I.e. what happens if the accumulated value drops below zero.)
2020-08-21 20:26:36 +02:00
herman ten brugge
a34a9775ba Fix char to ushort cast
tccgen.c:
- gen_cast: add check for char to ushort cast

tests/bug.c:
- remove tst1

tests/tests2/117_gcc_test.c:
- add tst_cast
2020-08-21 19:35:30 +02:00
herman ten brugge
696b765437 Fix switch/case
Fix switch for signed/unsigned switch
Also add new testcase 118
2020-08-18 20:05:53 +02:00
Willy Tarreau
b107f7bdd9 Fix switch/case on uint64_t
The switch/case operation was entirely performed on int64_t, resulting
in a warning and bad code to be emitted on 64 bit machines when used on
an unsigned long with a case range whose signed representation starts
positive and ends negative like in the example below:

  #include <limits.h>
  #include <stdio.h>
  #include <stdlib.h>

  int nbdg(unsigned long n)
  {
  	switch (n) {
  	case                    1UL ...                   9UL: return 1;
  	case                   10UL ...                  99UL: return 2;
  	case                  100UL ...                 999UL: return 3;
  	case                 1000UL ...                9999UL: return 4;
  	case                10000UL ...               99999UL: return 5;
  	case               100000UL ...              999999UL: return 6;
  	case              1000000UL ...             9999999UL: return 7;
  	case             10000000UL ...            99999999UL: return 8;
  	case            100000000UL ...           999999999UL: return 9;
  	case           1000000000UL ...          9999999999UL: return 10;
  	case          10000000000UL ...         99999999999UL: return 11;
  	case         100000000000UL ...        999999999999UL: return 12;
  	case        1000000000000UL ...       9999999999999UL: return 13;
  	case       10000000000000UL ...      99999999999999UL: return 14;
  	case      100000000000000UL ...     999999999999999UL: return 15;
  	case     1000000000000000UL ...    9999999999999999UL: return 16;
  	case    10000000000000000UL ...   99999999999999999UL: return 17;
  	case   100000000000000000UL ...  999999999999999999UL: return 18;
  	case  1000000000000000000UL ... 9999999999999999999UL: return 19; // this one
  	case 10000000000000000000UL ...             ULONG_MAX: return 20;
  	}
  	return 0;
  }

  int main(int argc, char **argv)
  {
  	unsigned long v = strtoul(argc > 1 ? argv[1] : "1111", NULL, 0);
  	printf("%lu : %d\n", v, nbdg(v));
  	return 0;
  }

  $ tcc dg.c
  dg.c:26: warning: empty case range
  $ x="";for i in 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0; do x=$x$i; ./a.out $x;done
  1 : 1
  12 : 2
  123 : 3
  1234 : 4
  12345 : 5
  123456 : 6
  1234567 : 7
  12345678 : 8
  123456789 : 9
  1234567890 : 10
  12345678901 : 11
  123456789012 : 12
  1234567890123 : 13
  12345678901234 : 14
  123456789012345 : 15
  1234567890123456 : 16
  12345678901234567 : 17
  123456789012345678 : 18
  1234567890123456789 : 0
  12345678901234567890 : 20

What this patch does is to use a separate set of signed and unsigned
case_cmp functions depending on whether the expression is signed or
unsigned, and also does this to decide when to emit the warning.

The bad code on output was caused by the removal of the unsigned bit
resulting from the signed sort, which causes only signed comparisons
to be emitted in the asm code. As such some sets could not match.

Note that there is no way to rely on the values only to sort properly
nor to emit the warning because we're effectively dealing with 65-bit
arithmetic here and any two values will have a different behavior
depending on the signed or unsigned expectation.

For unsigned expressions now the warning only happens when bounds are
switched, For signed expressions (e.g. if the input is signed long
above), the warning remains and the abnormal output as well. In both
cases this remains consistent with what gcc produces.
2020-08-18 11:27:27 +02:00
wanjochan
3613a11454 rm helper scripts newly added by me 2020-08-16 10:46:19 +08:00
wanjochan
777c017034 cleanup win32/tccwin_build.sh 2020-08-15 11:13:10 +08:00
Thomas Preud'homme
62c30a4a13 Fix typo in tcc-doc 2020-08-14 22:54:51 +01:00
herman ten brugge
4c9e3a5988 Update attribute bound_no_checking
tcctok.h:
- Add CONFIG_TCC_BCHECK  arround TOK_NO_BOUND_CHECK1/TOK_NO_BOUND_CHECK2

tccgen.c:
- Add CONFIG_TCC_BCHECK  arround TOK_NO_BOUND_CHECK1/TOK_NO_BOUND_CHECK2
- Undo alias definition in tccpp.c when function bound checking if off

tests/tests2/114_bound_signal.c:
- Test alias undo
- fix sleep problem
2020-08-14 06:35:47 +02:00
herman ten brugge
c740fa2795 Fix attribute patch for windows 2020-08-13 11:26:59 +02:00
herman ten brugge
50fe33f880 Add attribute bound_no_checking
tcc-doc.texi:
- Document attribute bound_no_checking

tcctok.h:
- Add bound_no_checking attribute

tcc.h:
- Add no_bcheck function attribute

tccgen.c:
- Use function attribute no_bcheck in merge_funcattr/parse_attribute/gen_function

bcheck.c:
- Fix no_checking in __bound_new_region/__bound_free/__bound_check

tests/tests2/114_bound_signal.c:
- Fix code with new attribute bound_no_checking

tests/tests2/103_implicit_memmove.c:
- Fix memmove prototype
2020-08-13 11:19:11 +02:00
wanjochan
5aaed43efd tune win32/tccwin_build.sh for libtccXX.dll 2020-08-13 12:34:03 +08:00
wanjochan
a06e8350aa helper script: build tcc32.exe tcc64.exe libtcc32.dll libtcc64.dll 2020-08-12 18:30:14 +08:00
wanjochan
cdf001c296 helper scripts for windows 2020-08-12 10:21:19 +08:00
herman ten brugge
70b16cb7f8 Fix argv/environ bound checking 2020-08-11 08:39:12 +02:00
herman ten brugge
8b8e714517 Fix bound checking for packed struct 2020-08-11 07:33:11 +02:00
herman ten brugge
09ed7e9557 Add bool debug type 2020-08-11 07:23:01 +02:00
herman ten brugge
e5da657c85 Fix testcase 95 for windows 2020-08-09 08:28:45 +02:00
herman ten brugge
dcb87d36fe Fix long bitfield
The fix is avoiding a core dump for radare2 project.
2020-08-09 07:50:34 +02:00
wanjochan
9085b38a71 add "libtcc.osx" entry to Makefile, for programs who need more pure libtcc.dylib without "@rpath/" config 2020-08-07 21:10:39 +08:00
herman ten brugge
3cfaaaf1eb Fix dll on arm.
Do not output the arm stack unwinding section (SHT_ARM_EXIDX).
2020-08-05 13:55:11 +02:00
herman ten brugge
a0a0f4d029 Add riscv dll support
Most support was already present.

riscv64-link.c:
- create_plt_entry:
 - remove DLLs unimplemented!
- relocate:
 - Add TCC_OUTPUT_DLL for R_RISCV_32, R_RISCV_64

tccelf.c:
- prepare_dynamic_rel:
 - Add R_RISCV_32, R_RISCV_64
2020-08-04 10:36:47 +02:00
herman ten brugge
b8fb2b02d9 Add arm dll support
Most support was already present.

arm-link.c:
- set RELOCATE_DLLPLT to 1
- create_plt_entry:
 - remove DLLs unimplemented!
 - leave code gen to relocate_plt. only set got_offset
- relocate_plt:
 - create code for got entry
- relocate:
 - Add TCC_OUTPUT_DLL for R_ARM_ABS32

tccelf.c:
- prepare_dynamic_rel:
 - Add R_ARM_ABS32
- alloc_sec_names:
 - Always add SHT_ARM_ATTRIBUTES section
- New function create_arm_attribute_section
- elf_output_file:
 - call create_arm_attribute_section
2020-08-04 09:15:42 +02:00
herman ten brugge
1da7159689 Add arm64 dll support
Most support was already present.

arm64-link.c:
- create_plt_entry:
 - remove DLLs unimplemented!
- relocate:
 - Add TCC_OUTPUT_DLL for R_AARCH64_ABS64/R_AARCH64_ABS32/R_AARCH64_PREL32

tccelf.c:
- prepare_dynamic_rel:
 - Add R_AARCH64_ABS64/R_AARCH64_ABS32/R_AARCH64_PREL32
- fill_got_entry:
 - Change 'TCC_TARGET_X86_64' into 'PTR_SIZE == 8'
2020-08-01 19:44:49 +02:00
herman ten brugge
d55a3f3362 Fix riscv64 compare problem.
Fix 64->32 bits sign/zero extention for riscv64.
2020-07-30 09:40:35 +02:00
herman ten brugge
d1ce34448f Faster load/store arm64
The load/store code is optimized to make better use of the offsets
present in the load/store instructions.
Also use GOT reloc's instead of ABS64 relocs.

arm64-gen.c/arm64_check_offset:
- New function to split offset used by load/store and by arm64_sym.

arm64-gen.c/arm64_sym:
- Use GOT reloc's instead of ABS64 relocs.

arm64-gen.c/load arm64-gen.c/store:
- Use new arm64_check_offset function.

arm64-gen.c/gen_bounds_prolog arm64-gen.c/gen_bounds_epilog:
- Use GOT reloc's instaed of ABS64 relocs.
2020-07-30 09:26:20 +02:00
Christian Jullien
58be11f701 Add L suffix to LDBL values. 2020-07-16 07:59:34 +02:00
Michael Matz
9b2329f66c riscv64: Work around qemu bug
old qemu (before april 2020) have a bug in the layout of
struct ucontext, so we get invalid values under qemu-userspace emulation
when inspecting the signal context.  Try to recognize this and
graciously error out instead of segfaulting in the backtracer routines.
2020-07-15 23:11:58 +02:00
Michael Matz
2e798523e4 Fix conversions of subnormals to long double
those need to be normalized when extending from float/double to
binary128.
2020-07-15 22:02:02 +02:00
Michael Matz
a614269794 riscv64: Fix a corner case
found in mpfr.  Expressions like "(longlong)i <= MAX_ULONGLONG" are
always true (not yet short-circuited in tcc), but still need to be
handled correctly in the backends.
2020-07-15 21:47:39 +02:00
Christian Jullien
92769362c7 Fix LDBL_xx values for aarch64 and riscv 2020-07-15 15:55:49 +02:00
herman ten brugge
c1e1c17c0a Move bound functions to tccgen.c
Move gen_bounded_ptr_add() and gen_bounded_ptr_deref() code to tccgen.c
No functional changes.
2020-07-12 10:55:40 +02:00
Christian Jullien
8314119662 USES: add mpc library 2020-07-11 20:00:37 +02:00
Christian Jullien
497678eee3 USES: just tested with gmp and mpfr on RPi 2020-07-11 07:42:18 +02:00
Christian Jullien
b5af2d3428 Add -C gcc compatible option which does currently nothing. This allows, among others, to compile gnumake from git ROOTB. 2020-07-11 06:41:44 +02:00
Christian Jullien
28e9fc1913 macos: 'make uninstall' also removes *.dylib 2020-07-10 10:38:36 +02:00
Christian Jullien
e19665c0d8 USES: add zlib 2020-07-10 06:35:02 +02:00
Steffen Nurpmeso
513a8b074d USES: s-nail 2020-07-09 23:52:43 +02:00
Avi Halachmi (:avih)
c69290fb0c macos: support arbitrary configure --libdir
Previously, after installation, only ../lib relative to the binary was
supported for finding libtcc.dylib, now any custom libdir.
2020-07-10 00:03:48 +03:00
Christian Jullien
6c94df6e2d macos: add path relative ../lib 2020-07-09 19:37:37 +02:00
Christian Jullien
6bd0ced239 Add USES file which list some software known to support tcc builds. 2020-07-09 17:21:23 +02:00
Christian Jullien
af0370a75d macos: add tcc version to libtcc.dylib. It can be shown with 'otool -L'. 2020-07-09 14:25:19 +02:00
Christian Jullien
b5a89c8c93 macos: tcc searches for libtcc.dyln in the same directory as its executable 2020-07-09 12:04:57 +02:00
Christian Jullien
1ea425811a macos: ldd does not exit, use otool instead 2020-07-09 08:03:31 +02:00
herman ten brugge
9d75f14107 Fix structure passing i386 PE
The orignal code does:
    push eax/edx/size
    call alloca
    pop  eax/edx/size

The pop does not work because the stack pointer has changed.
To make this also work with bound checking the code is now
using the stack probing from alloca.
2020-07-08 15:48:15 +02:00
herman ten brugge
20fa63488a Fix bounds checking
i386-gen.c:
- Fix large stack size alloca code.
  The returned value of alloca was not used corectly.

libtcc.c:
- Use __SIZE_TYPE__ for __builtin_offsetof

tccpp.c:
- Fix __MAYBE_REDIR and abort builtins.

tests/tests2/Makefile
- Run 117_gcc_test also with bound checking enabled
  This found the above problems.
2020-07-07 21:10:51 +02:00
Christian Jullien
49e2d06921 macos: initialize macho struct with memset which removes a clang warning on macOS. 2020-07-07 07:47:48 +02:00
herman ten brugge
fc05da3c0b Fix alloca and arm problems
alloca is only defined for i386 and x86_64
arm has __aeabi_ prefixes for mem... calls
2020-07-06 20:10:56 +02:00
Michael Matz
40671f76e4 Fix parsing of .s files
those aren't preprocessed, but our use of a fake file in
preprocess_start requires inline stack processing (which isn't done
without preprocessing).  Just don't try to setup anything requiring
preprocessing at all in this case.
2020-07-06 18:12:35 +02:00
Michael Matz
de06193d88 tccpp: Add -bench -E mode
for benchmarking the preprocessor, without having to use the PP_BENCH
macro.  No output will be produced for '-E -bench', so it's the raw
tokenization/preprocess speed.
2020-07-06 17:41:05 +02:00
grischka
2a0167adfe __builtin_/__bound_: A 'stay tiny' approach to the matter
tccgen.c:
- cleanup __builtin_... stuff
- merge __attribute((alias("sym"))) with __asm__("sym")
    Now one cannot have both, however for alias underscores are
    added if enabled.  For __asm__ they aren't.
tccpp.c:
- extend tcc_predefs accordingly.  Was generated with
  'cd tests/misc && tcc -run c2str.c tcc_predef.h tcc_predefs'
xxx-gen.c:
- move bcheck setjmp test to tccgen.c:gbound_args()
i386-gen.c:
- create win32 compatible stack space for big structures
tcctest.c:
- some cleanup + nicer output
2020-07-06 13:42:02 +02:00
grischka
6a4f3cf127 rework leading underscores
tested on win32/64 to pass the tests when enabled

- libtcc.c :
  let tcc define __leading_underscore if enabled
  tcc_add_symbol() : add _ automatically
- tccelf.c : remove tcc_get_symbol_err(), find_c_sym()
  currently symbol length is limited to 256 in several
  places, so we can use a fixed local buffer for now as well.
- win32/lib/crtinit.c : new file for init/fini
- lib/*.S, tests7* : use __leading_underscore
- bt-log.c: this file wont work relibaly if compiled with gcc
2020-07-06 13:00:47 +02:00
grischka
72277967ff some cleanups related to recent commits
- configure/Makefile : cleanup, really use CC_NAME
- tccasm.c : remove C99 construct that MSVC doesn't compile
- arm-gen.c, x86_64-gen.c, riscv64-gen.c, tccmacho.c : ditto
- arm64-gen.c: commit 383acf8eff wrote:
  "Instead of a cast, it would be better to pass the exact type."
  It is true that there are better solutions but it is not
  passing the exact type (I think).
- tcctest.c: revert "fix cast test for clang" 03646ad46f
  this obviously wants to test non-portable conversions
- 114_bound_signal.test: clock_nanosleep is too new for older
  linuxes, just use sleep() instead
2020-07-06 13:00:47 +02:00
grischka
0ee4989ed3 libtcc: accept tcc_define_symbol(s1, "sym=value", NULL)
Thus it can parse command-line -Dsym=value directly, for the
convenience of libtcc users or tcc itself

Also used in libtcc_test_mt.c to avoid strdup().
2020-07-06 13:00:47 +02:00
coltrane
90e9e34bec Add missing ws2tcpip.h which lets Microsoft Winsock Server sample compile ROOTB on Windows platform. 2020-07-06 09:47:09 +02:00
coltrane
e5d7e37157 Add missing ws2tcpip.h which lets tcc compile Microsoft Winsock Server sample on Windows platform. 2020-07-06 09:45:41 +02:00
herman ten brugge
9712aff9c0 Fix gcc testsuite problems
arm-gen.c:
- is_hgen_float_aggr/gfunc_sret: Fix for zero sized structs

arm64-gen.c:
- arm64_ldrs: Fix for zero sized structs
- arm64_sym: Use R_AARCH64_ABS64 instead of R_AARCH64_MOVW_UABS_G*
             This has same speed. See 117_gcc_test.c(tst_adr)
- load: Fix for zero sized structs and add VT_CONST | VT_LVAL support
- store: add VT_CONST | VT_LVAL support
- arm64_gen_bl_or_b: Allow branch. See 117_gcc_test.c(tst_branch)
- gen_bounds_prolog: Use R_AARCH64_ABS64 for bound checking
- gen_bounds_epilog: Use R_AARCH64_ABS64 for bound checking
- gfunc_call: Allow large stack
- arm64_gen_opic: Do not crash on large shift

riscv64-gen.c:
- load: Move type_size call. (move_reg set sv.type.ref NULL for VT_STRUCT)
- gfunc_call: Allow large stack
- gen_opil: Fix word mode calls

x86_64-gen.c:
- load: Fix for zero sized structs

libtcc.c:
- Add some defines for gcc testsuite (only most common)

tccgen.c:
- parse_builtin_params: Add types for builtins
- unary: Add builtins: __builtin_abort __builtin_memcpy __builtin_memcmp
                       __builtin_memmove __builtin_memset __builtin_strlen
                       __builtin_strcpy __builtin_strncpy __builtin_strcmp
                       __builtin_strncmp __builtin_strcat __builtin_strchr
                       __builtin_strdup __builtin_malloc __builtin_realloc
                       __builtin_calloc __builtin_free __builtin_alloca
- decl_initializer: Fix crash. See 60_errors_and_warnings(test_var_array)

tccmacho.c:
- Remove 'ret = 0'

tcctok.h:
- Add builtin/bound checking tokens

tests/gcctestsuite.sh:
- Add more counters and run execute tests

tests/bug.c
- Some remaining bugs in tcc (not complete)

tests/tests2/60_errors_and_warnings:
- Add test_var_array test

tests/tests2/117_gcc_test:
- New test

Results of gcctestsuite.sh for all targets:

linux:
x86_64: 3036 test(s) ok.  328 test(s) failed.  24 test(s) exe failed.
i386:   3037 test(s) ok.  327 test(s) failed.  24 test(s) exe failed.
arm:    2986 test(s) ok.  362 test(s) failed.  40 test(s) exe failed.
arm64:  2996 test(s) ok.  367 test(s) failed.  25 test(s) exe failed.
macos:  3031 test(s) ok.  332 test(s) failed.  25 test(s) exe failed.
riscv:  2948 test(s) ok.  401 test(s) failed.  39 test(s) exe failed.

windows:
x86_64: 3027 test(s) ok.  333 test(s) failed.  28 test(s) exe failed.
i386:   3029 test(s) ok.  331 test(s) failed.  28 test(s) exe failed.

linux with bounds checking:
x86_64: 3030 test(s) ok.  328 test(s) failed.  30 test(s) exe failed.
i386:   3028 test(s) ok.  327 test(s) failed.  33 test(s) exe failed.
arm:    2997 test(s) ok.  362 test(s) failed.  29 test(s) exe failed.
arm64:  2986 test(s) ok.  367 test(s) failed.  35 test(s) exe failed.
macos:  3026 test(s) ok.  332 test(s) failed.  30 test(s) exe failed.
riscv:  2936 test(s) ok.  409 test(s) failed.  43 test(s) exe failed.

windows with bounds checking:
x86_64: 3029 test(s) ok.  332 test(s) failed.  27 test(s) exe failed.
i386:   3027 test(s) ok.  331 test(s) failed.  30 test(s) exe failed.

all: fail for complex and vector types, nested functions
     and a lot of gcc defines/buitins.
arm/arm64/riscv: fail for asm and alloca.
riscv: fail with 'error: unimp: store(struct)'
2020-07-05 14:01:50 +02:00
Christian Jullien
6a15f15093 Fix coredump on linux when boostrapping tcc with -std=c11 2020-06-26 11:36:41 +02:00
herman ten brugge
03646ad46f Fix cast_test for clang.
The code was not portable and gcc could produce the same problem.
2020-06-25 09:29:45 +02:00
herman ten brugge
86992622dc do not disable all asm_test for macos 2020-06-25 09:10:11 +02:00
Christian Jullien
383acf8eff Fix warning detected by clang when passing unsigned int pointer when signed is expected. Instead of a cast, it would be better to pass the exact type. 2020-06-25 07:15:34 +02:00
herman ten brugge
50abaaeb0a Support clang on all targets
tccelf.c/tccpp.c/tccrun.c
Change: "..."+int into &"..."[int] to avoid clang warning.

tests/tcctest.c:
- Change __APPLE__ into __clang__
- Add undefined_function for clang
- disable most asm code for clang
- Fix res6/res8 for __builtin_constant_p
2020-06-24 20:51:18 +02:00
herman ten brugge
d5822b725e Fix ctype.h warning in lib/bcheck.c 2020-06-24 15:12:58 +02:00
Christian Jullien
f6e392a4af macos: add __builtin_flt_rounds. Forced to 1 which means 'to nearest' 2020-06-24 10:37:28 +02:00
Christian Jullien
f635de709e macos: clang -s option is obsolete - at least on macOS. 2020-06-24 07:06:48 +02:00
Christian Jullien
8bad5bfae5 macos: internally define _DONT_USE_CTYPE_INLINE_ otherwise, ctype.h macros may be defined multiple times in different translation units. 2020-06-23 15:53:01 +02:00
Christian Jullien
6b2bed447f macos: add some macros to replace few __builtin_xxx functions used in headers. 2020-06-23 12:27:03 +02:00
Christian Jullien
15e4f8b3b0 macos: Add DYLD_LIBRARY_PATH to tcc when configured with --disable-static - i.e. with .dylib support 2020-06-23 09:14:02 +02:00
Christian Jullien
9617ea6a3a macos: workaround to build tcc using tcc until .o object files generated by tcc are fully compatible with ar. Instead of ar, use 'tcc -ar' 2020-06-23 06:51:51 +02:00
herman ten brugge
3c53d54a43 Fix environ variable for macos. 2020-06-22 18:10:30 +02:00
herman ten brugge
039e4ec2a4 Call __bound_main_arg at startup
This uses a glibc feature present since constructor/destructor support was added.

Modify tccrun.c to call constructor with argc, argcv, envp.
In lib/bcheck.c use these values to register them in the splay tree.
Remove HAS_ENVIRON is lib/bcheck.c as it is not needed any more.
Modify win32/lib/crt1.c/win32/lib/dllcrt1.c/win32/lib/wincrt1.c to also
call constructor with argc, argcv, envp.
While implementing I saw that tccrun did nog call main with envp. Fixed it.
Also fix fetch_and_add_arm.S to make it work on armv6 (raspberry pi default).
2020-06-22 14:55:27 +02:00
Christian Jullien
0262f0eb1e macos: fix typo in conftest 2020-06-22 10:19:09 +02:00
Christian Jullien
f84e96fe81 macos: add 'c' option to conftest to get real compiler name and not an alias as with gcc on macOS 2020-06-22 10:12:18 +02:00
Christian Jullien
28d5c5e54f macos: apply readlink to get exact compiler name 2020-06-22 10:11:08 +02:00
Christian Jullien
9ad25d7257 Add clock_nanosleep emulation for macOS
modified:   tests/tests2/114_bound_signal.c
2020-06-22 07:37:54 +02:00
Christian Jullien
925f6704ce Add clock_nanosleep emulation for macOS 2020-06-22 07:36:15 +02:00
Christian Jullien
4d28120e9b macos: test 114 is not supported on macOS and this is not related to old gcc version 2020-06-21 11:49:29 +02:00
Christian Jullien
c69356635c macos: add darwin OS detection. 2020-06-21 10:58:36 +02:00
Christian Jullien
a3d1e9cd3d macos: Reorder C compiler detection so that conftest allows to boostrap tcc with tcc on macos. 2020-06-21 10:52:04 +02:00
Christian Jullien
8d9b83bd11 macOS configure correctly reports clang and version 2020-06-21 09:53:52 +02:00
Michael Matz
ba8980f492 limit gnu_inline hack to macos
some linux programs (kernel) really want to have 'extern inline'
functions be visible from other units, i.e. not be static, but also
mark them as always_inline.  That's -fgnu89-inline semantics, so it's
fine, but we don't (yet) implement this, so we can't make them static
just so.  But we do need this hack on MacOS due to some uses in
system headers (see commit f18f8651).

So, for now conditionalize the hack on Mach-O.
2020-06-21 02:03:46 +02:00
Michael Matz
c883d43ae5 fixes for deadlocks and dollars in asm
* tccelf code doesn't use USING_GLOBALS, hence must be called from
  outside the semaphore
* dollars aren't part of identifiers in asm mode
2020-06-21 01:45:35 +02:00
Michael Matz
18db8da7df Workaround old GCC viz indexed string literals
GCCs before gcc8 didn't deal with these where constants are
required.
2020-06-20 23:17:02 +02:00
Michael Matz
1711eb2ef3 macos: add overview comment 2020-06-20 22:25:08 +02:00
Michael Matz
d174af08f9 macos: Fix memtest
* free allocated memory
* fix weak symbols related to -run
* remove memtest from ignored tests for OSX
2020-06-20 22:17:08 +02:00
Michael Matz
ac86fb50cd macos: Tidy code 2020-06-20 22:17:08 +02:00
Michael Matz
c86760c1e9 macos: Read exported symbols from dylibs
up to now we simply assumed that any undefined symbols will be
provided by some shared libs on the cmdline.  Now we check this.
2020-06-20 22:17:08 +02:00
Michael Matz
fbfe6209be macos: Fix asm-c-connect-test
via some heavy-handed hackery in the ASM symbol handling in case
C symbols get a leading underscore (but ASM symbols do not).
But this is now like clang and GCC on Darwin work: asm symbols are
undecorated, C symbols get a _ prepended, so to connect both some
trickery is involved for the ASM symbols that don't have a _ prepended.
They must be included in the C symbol table (because that's what we use
to lookup also ASM labels), but they also must not disturb the normal
C symbol (which don't have the _ prepended), so they need some mangling.

A bit unsatisfying, but well.  So, add asm-c-connect-test to the working
ones for Darwin as well.
2020-06-20 22:17:08 +02:00
Michael Matz
3cf7bec12f macos: Enable all working tests
all except the below work now on MacOS, also as executable test,
not just with -run:
* dlltest - we don't support dylib generation (yet)
* memtest - tccmacho.c contains some leaks
* asm-c-connect-test - some confusion with underscores still
2020-06-20 22:17:08 +02:00
Michael Matz
f486b19f56 macos: bound_alloca symbol adjust
so that tests/boundtest.c links as well.
2020-06-20 22:17:08 +02:00
Michael Matz
f2e154e1e5 macos: Disable verbose linking output 2020-06-20 22:17:08 +02:00
Michael Matz
9ce5b4a691 macos: Adjust tcctest.c for clang
we need to disable or adjust some tests where clang behaves
slightly different from GCC:
* slight difference in __FILE__ behaviour
* difference (to less useful vs GCC) in computed #include
* difference in __builtin_constant_p
* attribute(weak, alias) isn't supported by clang on MacOS (though
  it could be, as Mach-O has the capabilities for this)
* the built-in assembler of clang is mediocre

this was all checked with
  Apple LLVM version 10.0.1 (clang-1001.0.46.4)
2020-06-20 22:17:08 +02:00
Michael Matz
4eff2b5f6a macos: more adjustments for OSX systems
* instead of /usr/include use the current SDK path as system
  include directory (/usr/include is empty with current tools)
  (this also removes the need to add these paths in individual
  Makefiles)
* define _DARWIN_C_SOURCE in tcc.h to get the full set of decls
  from system headers (e.g. vsnprintf), similar to _GNU_SOURCE
  (and don't define _ANSI_SOURCE in the main Makefile anymore)
* tests/tests2/Makefile: remove the -w flag, it's added when necessary
  in the rules generating the .expect files
2020-06-20 22:17:06 +02:00
Michael Matz
f18f865159 Handle always_inline as GNU inline
this is needed for multi-file testcases using stdio.h, as
the __sputc function is implemented as a extern inline
function (with gnu_inline attribute, but we don't support that for now).

Without this change that leads to multiply defined symbols when using
multiple units including stdio.h.

It also has an always_inline attribute, which we can use to guide our
behaviour, as in ISO-C an always_inline can't be defined with ISO
'extern inline' semantics.  This is the minimal change and not a full
implementation of GNU inline semantics, which would require thorough
testcases.

If __clang__ would be defined the header would make use of C99 semantics,
which would work for us.  It would also do that if _GNUC_ wouldn't be
defined.  But we can't do the latter (as the whole MacOSX SDK refuses
to be compiled with anything not defining that).  I haven't tested
defining __clang__, but suspect that's going to be problematic.
2020-06-20 22:14:56 +02:00
Michael Matz
5d2f4cb403 macos: various fixes
* alloca needs to be _alloca
* int64_t and uint64_t are also defined in <sys/_types/_int64_t.h>
  but as long long, not as long, so adjust out <stddef.h> to agree
  on Darwin
* define __APPLE_CC__ so that <TargetConditionals.h> correctly defines
  various macros like TARGET_OS_MAC and TARGET_CPU_X86_64
2020-06-20 22:14:56 +02:00
Michael Matz
b0b0e48409 macos: Use <dispatch.h> for locking
the global compiler lock can't be a POSIX non-shared semaphore on
Darwin (because not implemented there).  Use the dispatch framework.
2020-06-20 22:14:56 +02:00
Michael Matz
57ba50e611 macos: support bounds checking
* non-process-shared POSIX semaphores aren't supported on
  Darwin, we use the dispatch framework
* dlsym segfaults with RTLD_NEXT from JIT code, so we must not
  even try this for -run.  So we need to know in __bound_init
  if called from -run code, or from normal code, which means passing
  this down also from __bt_init and hence from the stub added in
  tcc_add_btstub
* Darwin uses different structures for <ctype.h> facilities, this
  merely adds a warning about this
* __libc_freeres doesn't exist
* for non -run modus the context (.prog_base member) is constructed
  incorrectly (uses symbol zero for trying to get at the load bias,
  which doesn't really work that way), on Mach-O this errors out
  (and could also error out on ELF).  For now deactivate this, which
  makes backtraces not be symbolic on MacOS for not -run.
2020-06-20 22:14:56 +02:00
Michael Matz
0b3c8360a0 macos: section syms, strtab, runtime
uncovered by the backtrace/boundcheck tests:

* handle STT_SECTION symbols
* call tcc_add_runtime (to get the bcheck.o/bt-exe.o files added)
* add .stab strtab into segments (we should probably add all stab
  syms to the output LC_SYMTAB eventually, but right now TCC uses
  32 bit stabs, while mach-o uses 32/64bit stabs
2020-06-20 22:14:56 +02:00
Michael Matz
91cb41330d macos: Adjust tests2.112 and tests2 Makefile
* <malloc.h> isn't as portable as <stdlib.h>
* skip 113_btdll.c on Darwin
* replace [...]\+ with [...]\{1,\} in the sed regex (basic REs
  have no + even some sed(1) accept it as \+, but bounds _are_ part
  of POSIX BREs)
2020-06-20 22:14:38 +02:00
Michael Matz
71b0634168 Add find_c_sym and friends
for handling leading underscores when looking up symbols.
Necessary on MacOS, as there C symbols have a '_' prepended.
get_sym_addr (replacing get_elf_sym_addr) gets an argument to
specify if bare/raw/ELF symbols should be looked up or if decorated
C symbols should be looked up.  That reflects into tcc_get_symbol.
tcc_add_symbol is _not_ yet changed, but probably should be.
2020-06-20 22:12:02 +02:00
Michael Matz
cc11750bda macos: Support .init_array and .fini_array
called different on Mach-O, but same functionality (list of pointers
to init and fini functions).
2020-06-20 22:12:02 +02:00
Michael Matz
ef730c4d2f macos: don't like in crt startup code
it's not needed with LC_MAIN executables.
2020-06-20 22:12:02 +02:00
Michael Matz
51f15d9971 macos: Deal with leading underscore on Mach-O
all C/C++/ObjC symbols in symbols tables have a leading underscore
in Mach-O.  Within TCC there's some confusion with tcc_add_symbol
(not adding it) and tcc_get_elf_symbol (not expecting it), and
resolve_syms (using dlsym, which doesn't expect it) and -run support.
But this sort of works.
2020-06-20 22:12:02 +02:00
Michael Matz
1ca209dad0 macos: set LC_MAIN entrypoint correctly
to the file offset of 'main' not simply to the start of TEXT.
2020-06-20 22:12:02 +02:00
Michael Matz
84c3fecf5e macos: Support external functions
these are resolved non-lazy for now.  We only need to generate
the jump stub (using the GOT slot that will be initialized due
to the non-lazy pointer marking, like with data symbols).  On
x86-64 we don't even need special marking of these stubs (with
S_SYMBOL_STUBS and associated additional indirect symbol entries),
as that's only used on i386 (where the stubs are self-modifying).

So, this now works:

extern int _printf(const char*, ...);
int _start(void)
{
  _printf("hello\n");
  return 0;
}
2020-06-20 22:12:02 +02:00
Michael Matz
d82e64c163 macos: handle undefined symbols a bit
at least data symbols coming from dylibs can be used now, as in the
below.  Note in the example that optind is defined in libc (really in
libsystem_c.dylib, reexported from libSystem.B.dylib):

static int loc;
extern int _optind;
int _start(void)
{
  _optind = 0;
  loc = 42 + _optind;
  return loc - 42;
}
2020-06-20 22:12:02 +02:00
Michael Matz
fab8787b23 macos: Fix GOT access to local defined symbols
if a GOT slot is required (due to codegen, indicated by
presence of some relocation types), then it needs to contain
the address of the wanted symbol, also when it's local and defined,
i.e. not overridable.  For simplicity we use a GOT slot for that as
well (other storage would require rewriting relocs and symbols,
as resolving of GOT relocs is hardwired to be based on s1->got).
But that means we need to fill in its indirect symbol mapping slot as
well, for which Mach-O provides a mean to say "not symbol based,
resolved locally".  So this fixes this testcase:

static int loc;
int _start(void)
{
  loc = 42;
  return loc - 42;
}

(where our codegen currently uses a GOT-based access for the write
by accident)
2020-06-20 22:12:02 +02:00
Michael Matz
6ebd463021 macos: dynamic symbol table and __got
this now sorts the symbols properly (local, global defined, undefined;
the latter two by name), marks the three ranges within LC_DYSYMTAB,
generates a __got section (non-lazy pointers) and slots for
relocations which need them, and the indirect symbol mapping for
them.

This doesn't yet deal with undefined symbols.  But it means compared to
last example now this also works, i.e. read access to _global_ data:

% cat simple3.c
int loc = 42;
int _start(void)
{
  return loc - 42;
}
2020-06-20 22:12:02 +02:00
Michael Matz
bbccb13566 for_each_element for all; add tcc_exit_state
this moves the for_each_element macro to tcc.h and adds a
tcc_exit_state (and uses it) pairing with tcc_enter_state.
2020-06-20 22:11:57 +02:00
Michael Matz
1320d85742 macos: Create symtab
this creates a proper LC_SYMTAB, with reasonable entries.  It's
not sorted, so not usable for LC_DYSYMTAB.  But 'nm -x -no-sort'
allows to see us some useful info.

This also relocates sections and symbols, so now this example
works as well (i.e. read access to static local data):

% cat simple2.c
static int loc = 42;
int main(void)
{
  return loc - 42;
}
2020-06-20 22:09:21 +02:00
Michael Matz
94066765ed macos: First cut at generating Mach-O executables
this does generate a working executable for a very simple
example input, e.g. this:

% cat simple.c
int main(void)
{
  return 0;
}
% ./tcc -B. -c simple.c
% ./tcc -nostdlib -B. simple.o -lc
% ./a.out && echo okay
okay

(the -lc is actually not necessary right now, see below).  This
has many limitations:

* no symbol table, hence no calls to external functions from
  e.g. libc, aka libSystemB
* no proper entry point (should be main, but is hardcoded to first
  real .text address)
* libSystemB is hardcoded, no other libs are supported (but again
  no external calls anyway)
* generated Mach-O executable is in old format: neither LC_DYLD_INFO
  no export tries for symbols are created (no symbol table at all!)
* the __LINKEDIT segment is faked and empty, as dyld doesn't like
  it empty even if no symbols point into it
* same with __DATA, dyld wants a non-empty writable segment which
  we enforce with useless data
* no relocations, hence no function call stubs (lazy or not) are
  generated
* hardcodes some other constants as well
2020-06-20 22:09:21 +02:00
Michael Matz
b882cad67e macos: Don't try to load dylibs or linker scripts
we ignore dylibs for now (can't inspect them yet for meta-info).
Also don't try to load GNU linker scripts, it's simply an unknown file
type (e.g. when mentioning Mach-O object files).
2020-06-20 22:09:21 +02:00
Michael Matz
9d2ce50d2f macos: Use SDK path for headers
until we have it properly encoded within TCC itself.
2020-06-20 22:09:21 +02:00
Michael Matz
6178e47345 macos: detect clang also when called as gcc 2020-06-20 22:09:21 +02:00
Michael Matz
032664bf7f macos: make Mach-O somewhat ELF_OBJ_ONLY
we only emit .o files in ELF format, but do use the .got building
from generic ELF code also on MacOS for -run.
2020-06-20 22:09:21 +02:00
Michael Matz
c16f5d2fe6 Fake __has_include handling
cctools for MacOS 10.14 (at least) unconditionally uses the
__has_include preprocessor directive (i.e. without checking
  if defined __has_include
as normally suggested for portable code).  So we need to handle
it a little bit.  For now we simply say "nope" aka evaluate to 0.
2020-06-20 22:09:21 +02:00
Michael Matz
34a5658564 macos: Add system include dir for building libs
we use xcrun to determine the correct path.  In the future those
should be determined at configure time or even runtime of tcc itself.
2020-06-20 22:09:17 +02:00
Michael Matz
4cc27b816f macos: Use newer MACOSX_DEPLOYMENT_TARGET
10.6 seems to still be supported on Mojave, but not 10.4
anymore.
2020-06-20 22:07:24 +02:00
Michael Matz
7b6931ed1f Fix some string literal expressions in initializers
Things like 'char x[] = { "foo"[1], 0 }' (which should initialize
a two-character array 'x' with "o\0").  See added testcase.
2020-06-20 22:00:18 +02:00
herman ten brugge
b2d351e0ec Fix fetch_and_add code
Change type from signed char to int.
Make assembly code work with tcc and gcc.
2020-06-18 07:21:48 +02:00
grischka
b5faa45d90 tccpp: faster next()
- call TOK_GET() as a function only for tokens with values
- get rid of 'next_nomacro_spc()'
- be sligtly more efficient in next()

This made about 4-5%+ speed in my tests.

Also: tcc.h: reorder tokens
2020-06-17 18:44:11 +02:00
grischka
781872517d tccpp.c: compile 'tcc_predefs' from string
It might have advantages in cases if tcc/libtcc does not
depend on extern files.

Also:
- apply "stray \\ ..." check to macros only. For files it
  was already checked. Add positive test.
2020-06-17 18:01:45 +02:00
grischka
cbef54653a tcc -MD: drop system includes and duplicates
Also:
- print filenames in errors for binary input files
  (was lost with the thread support recently)
2020-06-17 18:01:40 +02:00
grischka
e7a4140d28 tcc --help -v: cleanup
from e640ed1aeb

Also:
- cleanup -std, -O, -pthread
- tcc.h:win32: use win32-type include paths even for cross
  compilers (needed for loading tcc_predefs.h in cases)
- Makefile: simplify OSX .dylib clause
2020-06-17 17:41:46 +02:00
herman ten brugge
8fb8d88ea6 Add vla bound support for arm,arm64 and riscv64
tcctok.h:
- Add __bound_new_region

arm-gen.c arm64-gen.c riscv64-gen.c:
- Add bound checking support to gen_vla_alloc

tests/Makefile boundtest.c
- Add test18 vla bound checking test
2020-06-17 11:24:17 +02:00
herman ten brugge
44019e874f Fix debug info for functions
Add code for VT_FUNC.
Use octal number for unsigned int/unsigned long for 32 bits targets.
Add VT_BYTE | VT_UNSIGNED for targets with default unsigned signed char.
Remove extra ',' in default_debug struct.
2020-06-17 07:58:18 +02:00
herman ten brugge
0b8ee7364a Add bound checking to arm, arm64 and riscv64
Checked on:
- i386/x86_64 (linux/windows)
- arm/arm64 (rapberry pi)
- riscv64 (simulator)
Not tested for arm softfloat because raspberry pi does not support it.

Modifications:

Makefile:
  add arm-asm.c to arm64_FILES
  add riscv64-asm.c (new file) to riscv64_FILES

lib/Makefile:
  add fetch_and_add_arm.o(new file) to ARM_O
  add fetch_and_add_arm64.o(new file) to ARM64_O
  add fetch_and_add_riscv64.o(new file) to RISCV64_O
  add $(BCHECK_O) to OBJ-arm/OBJ-arm64/OBJ-riscv64

tcc.h:
  Enable CONFIG_TCC_BCHECK for arm32/arm64/riscv64
  Add arm-asm.c, riscv64-asm.c

tcctok.h:
  for arm use memmove4 instead of memcpy4
  for arm use memmove8 instead of memcpy8

tccgen.c:
  put_extern_sym2: for arm check memcpy/memmove/memset/memmove4/memmove8
                   only use alloca for i386/x86_64
  for arm use memmove4 instead of memcpy4
  for arm use memmove8 instead of memcpy8
  fix builtin_frame_address/builtin_return_address for arm/riscv64

tccrun.c:
  Add riscv64 support
  fix rt_getcontext/rt_get_caller_pc for arm

tccelf.c:
  tcc_load_dll: Print filename for bad architecture

libtcc.c:
  add arm-asm.c/riscv64-asm.c

tcc-doc.texi:
  Add arm, arm64, riscv64 support for bound checking

lib/bcheck.c:
  add __bound___aeabi_memcpy/__bound___aeabi_memmove
      __bound___aeabi_memmove4/__bound___aeabi_memmove8
      __bound___aeabi_memset for arm
  call fetch_and_add_arm/fetch_and_add_arm64/fetch_and_add_riscv64
  __bound_init: Fix type for start/end/ad
  __bound_malloc/__bound_memalign/__bound_realloc/__bound_calloc: Use size + 1

arm-gen.c:
  add bound checking code like i386/x86_64
  assign_regs: only malloc if nb_args != 0
  gen_opi/gen_opf: Fix reload problems

arm-link.c:
  relocate_plt: Fix address calculating

arm64-gen.c:
  add bound checking code like i386/x86_64
  load/store: remove VT_BOUNDED from sv->r
  arm64_hfa_aux/arm64_hfa_aux: Fix array code
  gfunc_prolog: only malloc if n != 0

arm64-link.c:
  code_reloc/gotplt_entry_type/relocate: add R_AARCH64_LDST64_ABS_LO12_NC
  relocate: Use addXXle instead of writeXXle

riscv64-gen.c:
  add bound checking code like i386/x86_64
  add NB_ASM_REGS/CONFIG_TCC_ASM

riscv64-link.c:
  relocate: Use addXXle instead of writeXXle

i386-gen.c/x86_64-gen.c
  gen_bounds_epilog: Fix code (unrelated)

tests/Makefile:
  add $(BTESTS) for arm/arm64/riscv64

tests/tests2/Makefile:
  Use 85 only on i386/x86_64 because of asm code
  Use 113 only on i386/x86_64 because of DLL code
  Add 112/114/115/116 for arm/arm64/riscv64
  Fix FILTER (failed on riscv64)

tests/boundtest.c:
  Only use alloca for i386/x86_64
2020-06-16 07:39:48 +02:00
Michael Matz
9eef33993a Fix type compatiblity of enums and ints
an enum must be compatible with one or more integer type,
so adjust the test accordingly.  That means the following
redeclarations should work:

  enum e6 { E1 = -1, E0 };
  void f3(enum e6);
  void f3(int);        // should work as int and e6 are compatible

while the following should not:

  void f4(enum e6 e);
  void f4(unsigned e); // should error as unsigned and e6 are incompatible
2020-06-05 16:02:08 +02:00
Michael Matz
068d5b3d20 pp: Move errors about stray backslashes
they were emitted too early, in particular also in macro
substitution which might turn out to not be stray in case it's
further stringified.  Check in next() instead.  Add two testcases
that an error is still emitted for obvious top-level baskslashes,
and that stringifying such a thing works.
2020-06-03 18:38:11 +02:00
Christian Jullien
e640ed1aeb Also support --help -v, i.e. arguments in different order. 2020-06-01 18:01:12 +02:00
Christian Jullien
bbb3f79bb8 Missied a commit in order to support -v --help the same way as gcc does 2020-06-01 17:23:20 +02:00
Christian Jullien
47363cbb97 Support -v --help the same way as gcc does 2020-06-01 17:11:11 +02:00
Michael Matz
ae14ef5426 riscv64: Fix printf warning
now that tcc_error also checks arguments.
2020-05-26 20:17:39 +02:00
herman ten brugge
3b617fdc53 Add sigsetjmp/siglongjmp bound checking support
tcctok.h:
- Add sigsetjmp/__sigsetjmp/siglongjmp

tccgen.c:
- redirect sigsetjmp/siglongjmp to bcheck.c code

i386-gen.c/x86_64-gen.c
- gcall_or_jmp: Set func_bound_add_epilog also when sigsetjmp is called
- gen_bounds_epilog: Only call __bound_local_new when needed (unrelated)

bcheck.c:
- Add __bound_siglongjmp
- __bound_setjmp/__bound_long_jump: Check no_checking
- Optimize __bound_local_delete (unrelated)

Modify testcase:
- 114_bound_signal
2020-05-25 12:26:55 +02:00
herman ten brugge
045632defb Fix gcc10 warnings
i386-gen.c:
- load/gen_opf: set v1.sym to NULL

lib/Makefile:
- Add -gstabs -fno-omit-frame-pointer -Wno-unused-function -Wno-unused-variable

lib/bt-log.c:
- tcc_backtrace: Prevent __builtin_frame_address warning

tccgen.c:
- struct_layout: Set t.t to VT_BYTE
- default_debug: Use octal instead of -1 to make size_t work

tccpp.c:
- tal_realloc_impl: Only memcpy when p set

x86_64-gen.c:
- gen_bounds_epilog: Do not save/restore rcx (not caller/callee saved)
                     This also made stack not aligned to 16 bytes.
2020-05-23 20:27:43 +02:00
herman ten brugge
b5b92c7d6d Add setjmp/longjmp bound checking support
tcctok.h:
- Add __bound_setjmp/setjmp/_setjmp/longjmp

tccgen.c:
- redirect setjmp/longjmp to bcheck.c code

i386-gen.c/x86_64-gen.c
- Change func_bound_alloca_used into func_bound_add_epilog
- Set func_bound_add_epilog also when setjmp is called

bcheck.c:
- Add __bound_setjmp/__bound_longjmp
- __bound_local_delete: remove setjmp if used in function
- __bound_exit: clear setjmp list and print statistic
- make malloc_redir more readable (unrelated)

New testcases:
- 115_bound_setjmp
- 116_bound_setjmp2
2020-05-23 20:02:41 +02:00
grischka
4429cef9f6 tccgen.c: merge more function attributes
Merge function attributes with those given given for the
prototype, also handle post-decl appearance such as

    void func() __attribute__((noreturn))
    {
    }

Also, some test fixes (unrelated).
2020-05-13 11:39:39 +02:00
grischka
7bb5454ef3 make SILENT=yes
This allows to run make more silently.

Also, turns off debug info for binaries by default,
but adds a switch to get it back easily

    ./configure --debug
2020-05-12 20:35:43 +02:00
Christian Jullien
92236bfe1d Rework help messages: split --version -v and -vv, display -m32/64 only when available on current plateform. 2020-05-11 16:23:48 +02:00
grischka
9c28349757 tccgen.c: cleanup debug support
from 3e731e3a78

tccgen.c:
- make 'struct default_debug' const
- pass TCCState* as parameter to tcc_debug_xxx functions
- always check tcc_state->do_debug before calling functions
- factor out tcc_debug_extern_sym()
- remove formats "%lld"/"%llu" (not reliable on windows)

xxx-gen files:
- set func_vt/var from caller
2020-05-11 11:41:56 +02:00
grischka
5bc1720776 tccgen.c: move 'alloca_used' complication to *-gen files
related to commit 8370bc03a1
2020-05-11 11:41:56 +02:00
Michael Matz
8de7c092f0 Support --version cmdline arg
for simplicity handles like -v (verbose), but enables the usual idiom
of configure scripts to use '$CC --version' to find out the compiler
variant and version.
2020-05-10 22:47:53 +02:00
herman ten brugge
29ba50da29 Fix some printf like functions 2020-05-05 09:00:24 +02:00
herman ten brugge
8370bc03a1 Allow signal handlers when bound checking
Disable generating bound_local_new/bound_local_delete when not needed.
Add new testcase 114_bound_signal.
2020-05-05 08:31:57 +02:00
herman ten brugge
973a14bb2f Fix symbolic debugging for -g -dt -run 2020-05-04 08:13:41 +02:00
herman ten brugge
3e731e3a78 Add symbolic debug support
This allows debugging with variables/structs/unions/enums/bitfields.

Add new functions:
- tcc_debug_stabs: store stabs debug info
- tcc_debug_stabn: store stabn debug info
- tcc_get_debug_info: generate stabs debug info
- tcc_debug_finish: store debug info in debug section
- tcc_add_debug_info: Add function debug info

Update functions:
- tcc_debug_end: free debug hash
- tcc_debug_funcstart: Generate correct function debug info
- tcc_debug_funcend: Finish debug info
- put_extern_sym2: Generate debug info for symbols
- pop_local_syms: Add debug info
- prev_scope: Add local symbols
2020-05-03 11:59:57 +02:00
Michael Matz
fb1fb8219c riscv64: fcvt.d.s doesn't need a rounding mode
it doesn't round so the RM field can be zero.  According to some
sourcs it should be set to zero by software in these cases, and
the binutils disassembler doesn't like us setting it to 7.

This shouldn't matter in practice, but who knows.
2020-04-16 00:02:32 +02:00
Michael Matz
2f94390223 musl: disable boundcheck tests
for now that doesn't work with musl libc.
2020-04-15 22:08:18 +02:00
Michael Matz
245f6a0d13 stdarg: always have the __builtin_va_* available
This makes available the __builtin_va_list type and __builtin variants
of va_start, va_arg, va_copy and va_end.  We do this via a header file
that's prepended to all compilations always (except if merely
preprocessing): tcc_predefs.h.  That header could also be used
for predefining other builtins in the future.

We don't need the define hacks for musl anymore with this.

Also fix x86_64 gfunc_prologue to reserve enoug space for the
full va_list structure, not just 16 bytes.
2020-04-15 22:06:52 +02:00
Michael Matz
8c6143d86f Fix stdarg on x86-64
this partly reverts 1803762e3 to fix stdarg on x86-64 again.  I've tried
to retain the apple specific changes from that commit.
Also include stdarg.h first in tcc.h, maybe that helps as well.
2020-04-15 04:49:34 +02:00
Robert Hoelzl
1803762e3f Make tcclib1.a compile on macOS again
When compiling on macOS (at least in version 10.12) the TCC compiler failed
to compile libtcc1.a. Three problems were solved:
 - The predefined macro "__APPLE__" is now available, as it is tested in the
   libc darwin header files
 - the libtcc1 Makefile defined _ANSI_SOURCE, although it used signals
 - stdargs.h defined va_list differently from the darwin libc.
   If the darwin standard library was included BEFORE stdargs this caused
   problems.
 - the darwin libc generated a warning if GCC < 4 was used
 - additional defines are predefined now to make darwin libc headers compile.
2020-04-15 02:56:24 +02:00
Michael Matz
38ab621b55 Factor out common type combination
as there's overlap between handling types for binary and ternay
operations.  Factor this into a single routine (combine_types).
This uses the structure that gen_op was following, and expr_cond
was using as well in the past, which I find easier to reconvene
with the standard language.  But it reuses the new functions for
diagnostics to improve (a little) on what GCC or clang produce :)
2020-04-15 02:44:12 +02:00
Michael Matz
c085645f98 Expect c99 support in tcctest.c
the support for the macro GCC_MAJOR is gone since 2017, and it's
fairly doubtful that anyone serious is using gcc 2.95.

Also adds a test for the ternary ops typing rules: 'x?bool:bool' has
to promote to int.
2020-04-15 02:28:23 +02:00
Michael Matz
00fbf65524 Move type_incompatibility_error earlier
also move type_incompatibility_warning and type_to_str.
2020-04-15 02:11:05 +02:00
Michael Matz
096c93c0c6 Fix interaction of (local) labels and stmt exprs
as per testcase.  We must not reset token.sym_label twice with
kept symbols.  This is no problem for non-label symbols because those
aren't generated on demand when mentioning them.
2020-04-14 22:43:13 +02:00
grischka
6696da2f61 win32: long double as distinct C-type
On windows. there is no long double really IOW it is the
same as double.  However setting the VT_LONG flag in
combination with VT_DOUBLE allows to keep track of the
original type for the purpose of '_Generic() or more
accurate type warnings.
2020-04-11 22:03:09 +02:00
grischka
d019586378 win32/include/math.h: rint/trunc: pop fp stack
... in order to avoid fp stack overflow (see test below).

#include <math.h>
#include <stdio.h>
int main()
{
   printf("%f %f %f %f\n", trunc(1.2), rint(1.2), trunc(1.2), rint(1.2));
   printf("%f %f %f %f\n", trunc(1.2), rint(1.2), trunc(1.2), rint(1.2));
   printf("%f %f %f %f\n", trunc(1.2), rint(1.2), trunc(1.2), rintl(1.2));
}

Also in rintl:
- 'long double' is not a ten-byte float on windows.
2020-04-11 21:45:57 +02:00
Tyge
024214af2d Finalizing math.h fixes:
- Updated msvcrt.def with symbols from 64bit version of dll - it contains the float math functions missing in the 32bit dll.
- Made sure this patch only apply to to WIN32 and WIN64. For WIN32 float functions calls the double variants, on 64bit they are called natively.
2020-04-11 02:29:51 +02:00
Tyge
df67d8617b Minimum changes to make all float variants of math.h functions work,
by calling the double functions and removing unsupported __asm implementations using "=t".
This patch also enables the double version of logb(double).

Note: None of the 'long double' variants works though - could easily be fixed
by aliasing the double equvalents for completeness/compability.
2020-04-07 20:18:51 +02:00
wanjochan
c386ca91c6 OSX: libtcc.dylib Makefile fix 2020-03-22 20:36:14 +08:00
Christian Jullien
5ade19c421 Add a test function which verifies we can pass a struct ptr to va_arg for all supported architectures. The bug has been identify by trying to compile FFTW-3.3.8. 2020-03-22 08:40:35 +01:00
Christian Jullien
ec0e93616f Fix arm64-gen.c when passing a struct ptr to va_arg. 2020-03-22 08:26:03 +01:00
wanjochan
6fa78a3635 OSX: make libtcc.dylib 2020-03-21 23:57:00 +08:00
wanjochan
4caa9a4cc7 relocate_syms() should using !(nostdlib) for parameter "int do_resolve" 2020-03-14 16:17:39 +08:00
matthias
704b602184 instruduce C2x _Static_assert syntaxe 2020-03-04 11:35:34 +01:00
matthias
cb041f11f6 improve _Static_assert
Fix static assert to support literal string instead of just printing
the sring of the current token as it use to be

so we can now use _Static_assert(0, "0" "1") which will print
__FILE__ __LINE__ error: 01
2020-03-04 11:35:34 +01:00
Sizhe Zhao
e050ae845e win32/build-tcc.bat: clean .o in win32/lib
commit ef42295fe8 intrduced 4 .o files to
win32/lib. But they (bcheck.o, bt-dll.o, bt-exe.o and bt-log.o) are not
removed by "win32/build-tcc.bat -clean". This commit should fix it.
2020-02-19 00:43:41 +01:00
Udo
923100c498 Better follow spacing style. (only changed formatting) 2020-02-18 21:11:49 +01:00
Udo
9272fac7c4 rework type coercion in ternary expr (a bit) and uncomment previously failing test. Be more explicit in diagnostic messages. 2020-02-17 18:25:43 +01:00
Udo
a9e7fe19c7 extend test 03_struct for attr. __cleanup__ 2020-02-09 18:31:19 +01:00
Udo
89b3cf0b87 warn if attr. __cleanup__ is given in type decl. (Allow this as an extension?) 2020-02-09 18:21:59 +01:00
Udo
c092f2ed61 Check if symbol given for attr. cleanup is actually a function 2020-02-07 23:23:31 +01:00
grischka
7e901299bf Rework expr_infix
- revert const-folding in gvtst() and put it back into
  expr_landor().  Although it did make sense, one reason
  not to do it is __builtin_constant_p() which may return
  true when it shouldn't because of nocode_wanted, see test.

- tccgen_init() can do init_prec(), also for tcc -E.

- for nostalgic reasons, keep the original expression parser
  functions in the source.

- Makefile: remove stale stuff
2020-01-22 21:57:19 +01:00
Michael Matz
aeac24de98 Rework expr_landor
so that it also is called from the precedence parser.  This
is complicated by the fact that something needs to be done before
the second operand is parsed in a single pass compiler, so it
doesn't quite fit into expr_infix itself.  It turns out the smallest
code changes result when expr_landor remains separate.  But it can
be tidied a bit.
2020-01-20 05:48:48 +01:00
Michael Matz
23a8bac7b5 Use precedence parser for expressions
This is smaller and uses less stack depth per expression (eight function
calls from expr_or to get down to a unary).  It's a tiny bit faster
depending on how good the branch predictor is, on my machine a wash.
2020-01-20 05:48:48 +01:00
Michael Matz
fdeeb62e28 Fix symbol versions with shared libs
ELF files that refer to shared libs containing sym-versions, but
don't refer to any dynamic symbols with symbol versions (should happen
only with very simple shared libs) would generate an empty .gnu.version_r
section.  Some dynamic linker contain bugs in that they don't check
the section size or DT_VERNEEDNUM (which are both zero for such files
we generate) before accessing the first entry, and then bail out with
a message like

./a.exe: error while loading shared libraries: ./a1.so: unsupported
 version 25960 of Verneed record

(where the "version number" actually comes from neighboring bytes
from different sections).

So, there's not much choice, we simply must not generate such section.
2020-01-20 05:31:09 +01:00
grischka
d79e1dee8c backtrace: test with DLLs
- tests2/113_btdll.c: test handling multiple stabs infos
Also:
- libtcc.c: remove _ISOC99_SOURCE pre-defines.  It is causing
  strange warnings such as 'strdup not declared'

- i386/x86_64-gen.c cleanup bounds_pro/epilog.  This discards
  the extra code for main's argv.  If needed, __argv might be
  processed instead.

- tccgen.c:block(): reduce stackspace usage.  For example with
  code like "if (..) ... else if (..) ... else if (..)... "
  considerable numbers of nested block() calls may occur.

  Before that most stack space used when compiling itself was
  for libtcc.c:tcc_set_linker().

  Now it's rather this construct at tccpp.c:2765: in next_nomacro1():

  if (!((isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
        || c == '.'
        || ((c == '+' || c == '-')
        ...
2020-01-19 11:46:07 +01:00
Michael Matz
a5f6e6189e Make 112_backtrace/bcheck_123 more robust
the strcat checker first checks dest for overlap, then src.
If the padding byte between b[] and the pad[] arrays happens to be zero
the dest check would have succeeded and the src test failed.  If that
padding byte would be zero the dest check would trigger first.
As we can't influence the padding byte (only the b[] and pad[] arrays)
it was random if the dest or src checks triggered.

This makes it reliably trigger the dest check first.
2020-01-18 03:06:44 +01:00
grischka
2b7cffac74 fixes for previous commit 2020-01-18 01:22:28 +01:00
gr
ef42295fe8 tccrun.c: standalone backtraces with -bt[N] or -b
This makes it possible to get backtraces with executables
(including DLLs/SOs) like we had it already with -g -run.

Option -b includes -bt, and -bt includes -g.

- new file lib/bt-exe.c: used to link rt_printline and the
  exception handler from tccrun.c into executables/DLLs.

- new file lib/bt-log.c: provides a function that may be
  called from user code to print out a backtrace with a
  message (currently for i386/x86_64 only):

     int (*tcc_backtrace)(const char *fmt, ...);

  As an extra hack, if 'fmt' is prefixed like "^file.c^..."
  then the backtrace will skip calls from within 'file.c'.

- new file lib/bt-dll.c:  used on win32 to link the backtrace
  and bcheck functions with the main module at runtime

- bcheck.c: now uses the tcc_backtrace function from above

- tccgen.c: minor cleanups

- tccelf.c: stab sections get SHF_ALLOC for easy access.
  Also in relocate_section(): 64bit relocations for stabs
  in DLLs cannot work.  To find DLL addresses, the DLL base
  is added manually in tccrun.c via rc.prog_base instead.

- tccpe.c: there are some changes to allow merging sections,
  used to merge .finit_array into .data in the first place.

- tccpp.c: tcc -run now #defines __TCC_RUN__
  also: refactor a line in tal_realloc that was incompatible
  with bcheck

- tcctest.c: fixed a problem with r12 which tcc cannot preserve
  as well as gcc does.

- tests2/112_backtrace.c: test the feature and the bcheck test18
  that previously was in boundtest.c
2020-01-17 22:58:39 +01:00
herman ten brugge
4092b05068 Exclude ellipsis functions from bounds checking.
This fails on i386.
2020-01-16 09:40:33 +01:00
Christian Jullien
c2976962da Merge branch 'mob' of git://repo.or.cz/tinycc into mypatch 2020-01-16 09:00:26 +01:00
Christian Jullien
c7e3d5d7a3 Add _ISOCxx_SOURCE glibc compatible macros. 2020-01-16 08:58:43 +01:00
herman ten brugge
0d7c40b948 Call pop_local_syms before gfunc_epilog 2020-01-16 08:24:17 +01:00
Michael Matz
65f2fe390c Cleanup new bound checking code
remove quadratic loops by not using side tables; address-taken
can simply be a flag per local sym, and the lbounds section can
be filled after symbols go out of scope at which point we know
if the address was taken, so that there's no need to compress it
again after the funcion is done.
2020-01-16 01:19:59 +01:00
Michael Matz
4a70b2bc2d Fix handling of unevaluated subexpression of const
we were emitting error messages for something like
'static int i = 2 || 1/0', even though the exception would be in
the unevaluated part.  This doesn't destroy const-ness, so we must
accept it.  This requires splitting the nocode_wanted values a bit more,
so that nocode_wanted due to const_wanted can be differentiated from
nocode_wanted due to non-evaluation.
2020-01-15 23:32:40 +01:00
herman ten brugge
3877618785 Update bound checking code.
Add __attribute__((constructor)) to __bounds_init.
- remove tcc_add_bcheck from i386-link.c and x86_64-link.c
- add simplified tcc_add_bcheck to tccelf.c
- Update tccrun.c to call constructor/destructor.
Set dynsym sh_info to number of local symbols in tccelf.c
Reduce stack size when bounds checking is enabled.
Added variable TCC_LIBBCHECK for windows support.
Add signal stack to detect stack overflow.
Add all & parameters in lbound_section and remove them if not used.
Close fd in tcc_relocate in tccrun.c
Fix section type constructor/destructor in tccelf.c
Add check code in tests/boundtest.c for mem/str functions.
Remove -ba from documentation.
Add bounds check signal info in documentation.

bcheck.c:
- Fix initial_pool alignment.
. Fix printf statements.
. Add prototypes for all external interface functions.
- Add TCC_BOUNDS_WARN_POINTER_ADD environment variable.
. Add ctype and errno data.
- Fix alloca when multithreading is used.
- Add lock for __bound_checking and __bound_never_fatal.
- Catch pthread_create and use locks when called.
- Detect in loaded in shared lib and use locks when found
- Use spin locks instead of semaphore locks.
- Make spin locked code as small as possible.
- Fix mem/str functions checking.
- Fix overlap checking mem/str functions.
2020-01-15 08:53:19 +01:00
Christian Jullien
0d6801b130 C11, section 7.2: The macro static_assert expands to _Static_assert. This macro was missing on Windows 2020-01-14 07:41:58 +01:00
herman ten brugge
269042503e Fix sellinux pointer code in tccrun.
Free all memory on exit in __bound_exit.
2019-12-23 20:23:18 +01:00
Michael Matz
f150f93854 Fix the get_asm_string fail on i386 in another way
the problem is that new debian GCC enabled -fPIC or -fPIE by
default, causing the mentioned compile error.
2019-12-17 17:54:54 +01:00
Giovanni Mascellani
43fb5a72e7
tcctest: explain why i386 is not tested 2019-12-17 12:36:02 +01:00
Michael Matz
1d4d74d6d0 Use explicit signed char in char_short_test
as 'char' is unsigned on some architectures, so the tests weren't
testing what they were supposed to.
2019-12-17 04:56:54 +01:00
Michael Matz
c8ca64d28b Adjust return value promotion for some archs
this is a bit complicated: for i386 and x86-64 we really need to
extend return values ourself, as the common code now does.  For arm64
this at least preserves old behaviour.  For riscv64 we don't have to
extend ourself but can expect things to be extended up to int (this
matters for var-args tests, when the sign-extension to int64 needs to
happen explicitely).  As the extensions are useless, don't do them.

And for arm32 we actually can't express GCC behaviour: the callee side
expects the return value to be correctly extended to int32, but
remembers the original type.  In case the ultimate target type for the
call result is only int, no further extension is done.  But in case
the target type is e.g. int64 an extension happens, but not from int32
but from the original type.  We don't know the ultimate target type,
so we have to choose a type to put into vtop:
* original type (plus VT_MUSTCAST) - this looses when the ultimate
  target is int (GCC: no cast, TCC: a cast)
* int (without MUSTCAST) - this looses when the ultimate target is
  int64 (GCC: cast from original type, TCC: cast from int)
This difference can only be seen with undefined sources, like the
testcases, so it doesn't seem worthwhile to try an make it work, just
disable the test on arm and choose the second variant as that generates
less code.
2019-12-17 01:46:06 +01:00
Michael Matz
2d17e5a6c4 riscv64: adjust for cast changes
gfunc_call plays with types and needs to retain the unsignedness
now (this was a latent problem before commit 35475b5).
2019-12-17 00:48:57 +01:00
grischka
d30d68d738 #pragma comment(option, "file.c")
This allows adding files or libraries from
   #pragma comment(option, ...)

Also, {f}/file.c will be expanded with the directory of
the current source, that is the file that has the #pragma
2019-12-16 22:48:31 +01:00
grischka
a64353ce71 tccgen.c: generic char/short promotion for function return values 2019-12-16 21:58:32 +01:00
grischka
89372dc482 update gen_cast 2019-12-16 21:37:44 +01:00
grischka
35475b5423 remove VT_LVAL_BYTE etc.
For some reason there was no point for that anymore.
2019-12-16 20:59:23 +01:00
grischka
5914f4d57d tccgen.c: cleanup reg classes
wrap some copy&paste code into functions
2019-12-16 20:44:48 +01:00
grischka
ff3b5ee91c -bench fix
Put total_lines etc. into TCCState.  Also, initialize
the predefined compiler types for the preprocessor too.
tccpe.c: fix BaseOfCode if .init section present (with tcc -b)
2019-12-16 20:17:10 +01:00
Michael Matz
b476a5f478 Readd lost error on local static function decls
see testcase: block scope decls for functions can't use static
(allowed is only extern or none).  This got lost in commit 85690480.
2019-12-16 07:00:26 +01:00
Michael Matz
6cb68c3a17 arm64: fix some casts
in the new common backtrace/context code.
2019-12-15 00:05:30 +01:00
Michael Matz
2fb79a6326 Fix some races
protect some more accesses to global data with the semaphore.
(And for the testcase: don't just write into global data, use local
copies; it's not important for speed here).
2019-12-14 23:58:45 +01:00
grischka
65f74a4df0 tccrun.c: better stab debug support
* a major revision of the rt_printline() feature in
  tccrun.c to report file:linenumber more correctly.

* minor changes to the stab info produced by the
  compiler in tccgen.c

However stab addresses are limited to 32 bits.  I added
a work around:

    if (sizeof pc == 8)
        pc |= wanted_pc & 0xffffffff00000000ULL;

However GDB has problems with that too.
2019-12-14 17:48:50 +01:00
grischka
56db092ab7 bcheck cleanup
- revert Makefiles to state before last bcheck additions
  Instead, just load bcheck.o explicitly if that is
  what is wanted.

- move tcc_add_bcheck() to the <target>-link.c files and
  remove revently added arguments.  This function is to
  support tccelf.c with linking, not for tccgen.c to
  support compilation.

- remove -ba option:  It said:
  "-ba  Enable better address checking with bounds checker"
  Okay, if it is better then to have it is not an option.

- remove va_copy. It is C99 and we try to stay C89 in tinycc
  when possible.  For example, MS compilers do not have va_copy.

- win64: revert any 'fixes' to alloca
  It was correct as it was before, except for bound_checking
  where it was not implemented.  This should now work too.

- remove parasitic filename:linenum features
  Such feature is already present with rt_printline in
  tccrun.c.  If it doesn't work it can be fixed.

- revert changes to gen_bounded_ptr_add()
  gen_bounded_ptr_add() was working as it should before
  (mostly).  For the sake of simplicity I switched it to
  CDECL.  Anyway, FASTCALL means SLOWCALL with tinycc.

In exchange you get one addition which is required for
bounds_cnecking function arguments.  The important thing
is to check them *BEFORE* they are loaded into registers.
New function gbound_args() does that.

In any case, code instrumentation with the bounds-check
functions as such now seems to work flawlessly again,
which means when they are inserted as NOPs, any code that
tcc can compile, seems to behave just the same as without
them.

What these functions then do when fully enabled, is a
differnt story.  I did not touch this.
2019-12-14 13:26:18 +01:00
herman ten brugge
a86f47889c Fix debug info 2019-12-13 15:07:02 +01:00
herman ten brugge
87639aae7c Add linenumber filename support for bounds checking. 2019-12-13 13:45:09 +01:00
herman ten brugge
56e70bfa31 Fix bounds checking new functions.
There was a problem with strncpy and strncmp.
Made bound_ptr_add and bound_ptr_indir a little bit faster.
Fix statistic counter types. Change long into long long.
2019-12-13 10:02:20 +01:00
herman ten brugge
39c0ff311d Add new bounds checking functions.
The following functions are now also bounds checked:
memcmp, strncpy, strcmp, strncmp, strcat, strchr, strdup.

Add statistics code for bounds checking functions.
The statistics can be printed by settings environment variable
"TCC_BOUNDS_PRINT_STATISTIC".

Enabled more tests in test/Makefile.
2019-12-12 20:49:35 +01:00
herman ten brugge
35512be1ee Fix typo with -ba option 2019-12-12 14:21:07 +01:00
herman ten brugge
75145ddc1a Add -ba option for bounds_checking 2019-12-12 13:29:45 +01:00
herman ten brugge
4a2e33d160 Update bounds checking.
The bounds checking code has now enabled gen_bounded_ptr_add tests.
This makes the code slower but finds more errors.
I had to correct some things in tcc to make it work.
- Fixed off by one in lib/bcheck.c
- Corrected tccelf.c sym_versions.
- Disabled USE_TAL when using bounds checking.
- Fixed cstr_printf va_start.
- Fixed tests/tests2/46_grep.c off by one error.
- Updated gen_bounded_ptr_add in x86_64-gen.c
- Fixed x86_64-link.c pointer diff.
For gen_vla_alloc now always use alloca call when bounds checking.
Added line/filename in %rax before bound calls to find location of error.
2019-12-12 12:56:06 +01:00
Michael Matz
ce4eafb34f Include some headers in new multi-thread test
for usleep and gettimeofday.
2019-12-12 03:31:21 +01:00
Michael Matz
11fc58fa13 Fix parallel make targets
my last patch here fixed a missing dependency, but in the wrong
way.  It would build some object files twice, which could race.
The lib/all target already builds both libtcc{,b}1.a libs, so
a simple dependency is enough.
2019-12-12 02:00:13 +01:00
Michael Matz
90e09ed75f Disable thumb code generation on tcctest.gcc
this breaks getting the alignment of functions via bit masking
which we assume to work in one test.
2019-12-12 01:52:50 +01:00
Michael Matz
83f822d0cd Also parse -Dfoo in libtcc_test_mt
otherwise the -DTCC_ARM_VFP doesn't get through.
2019-12-12 01:39:58 +01:00
Michael Matz
8b23662d53 Fix libtcc_test_mt with lib64
we need to pass NATIVE_DEFINES, and we need to actually parse
and pass them into the state.
2019-12-11 17:57:43 +01:00
herman ten brugge
b3893baa45 Fix3 alloca on x86_64 windows 2019-12-11 14:26:27 +01:00
herman ten brugge
b45a8d456d Fix2 alloca on x86_64 windows 2019-12-11 14:22:01 +01:00
herman ten brugge
426d32af23 Fix alloca on x86_64 windows 2019-12-11 14:06:15 +01:00
herman ten brugge
a0bc149b0c Fix bounds checking after concurrently commit 2019-12-11 12:07:48 +01:00
grischka
72729d8e36 allow libtcc states to be used concurrently
This allows creation of TCCStates and operation with API
calls independently from each other, even from threads.

Frontend (option parsing/libtcc.c) and backend (linker/tccelf.c)
now depend only on the TCCState (s1) argument.

Compilation per se (tccpp.c, tccgen.c) is still using
globals for convenience.  There is only one entry point
to this section which is tcc_compile() which is protected
by a semaphore.

There are some hacks involved to avoid too many changes,
as well as some changes in order to avoid too many hacks ;)

The test libtcc_test_mt.c shows the feature.  Except this
new file the patch adds 87 lines overall.
2019-12-11 02:36:19 +01:00
grischka
6082dd62bb tcc -vv ... : show objects loaded from archives 2019-12-10 20:55:57 +01:00
grischka
df349ddc43 versym cleanup
get rid of some globals, in the first place.  Also, for the
PE target, ifdef out ELF executable creation.
2019-12-10 20:41:35 +01:00
herman ten brugge
4d297d354c Add bound checking print heap 2019-12-10 19:47:33 +01:00
Michael Matz
fb22e0c12d Fix type/r/r2 confusion differently
on i386 111_conversion.c breaks when save_reg_upstack isn't careful
about r2 and type mismatches.  The bcheck patches fixed this by
enlarging the stack slot beyond the natural type, this variant simply
avoids saving the second register is the type indicates that it isn't
needed.

Adds also a comment how this should ideally work, namely that type
and r/r2 entries in the vstack are consistent.  In the 111_conversion
testcase it's specifically gen_cast via gen_cvt_ftoi that breaks
this, but there more general code broken as well, so that would deserve
a careful fixup based on some additional asserts.
2019-12-10 17:49:04 +01:00
Michael Matz
ac2a61d1b3 Add dependency on libtccb1.a
otherwise parallel makes might throw errors.
2019-12-10 17:48:23 +01:00
Michael Matz
353db307ed Fix compile warning with cross compilers
'make i386-tcc' on a x86-64 host gave a warning about the
unconditionally declared static tcc_add_bcheck function.
2019-12-10 16:56:10 +01:00
herman ten brugge
88dd577302 Disable bounds_check1_test on arm 2019-12-10 09:39:45 +01:00
herman ten brugge
17850a51f5 Fix bounds checking on targets with no bcheck.c 2019-12-10 08:44:44 +01:00
herman ten brugge
4461f38a9e Fix bounds checking for linux/windows 2019-12-10 08:07:25 +01:00
Michael Matz
474f95dda8 Fix setting of options
now that the type of boolean options is uchar set_flag() needs
an accompanying change.
2019-12-05 17:04:04 +01:00
Michael Matz
1dc92f8ff8 Fix indentation and run_test type
tcc_state.run_test is used as counter, not flag, so int is appropriate.
Also fix indentation garbled by last patch.
2019-12-02 19:20:56 +01:00
Sergey Sushilin
4873f6fada use uchar instead of int to save memory 2019-12-01 23:22:57 +03:00
Sergey Sushilin
14fc6b6dcb use size_t instead of int when work with strings 2019-12-01 22:45:42 +03:00
herman ten brugge
df72b8d487 Add windows constructor/destructor support 2019-11-27 18:29:12 +01:00
Michael Matz
4e9ce59fe8 Workaround false positive warning 2019-11-27 17:35:24 +01:00
Michael Matz
8a93ce106a elf: rewrite version support
so it isn't quadratic in number of symbols.  It's still quadratic
in number of lib/version combinations (at library load time the
sym versions are internalized), but that's much less a problem as
in practice only glibc uses sym versioning.
2019-11-25 21:06:07 +01:00
Christian Jullien
25781e4552 Fix float conversion in arm64 backend 2019-11-08 07:55:05 +01:00
Jookia
f420259ee5 arm: Don't override syscall implementation 2019-11-06 01:01:56 +11:00
herman ten brugge
96f1fb1da0 rename testcase 2019-10-29 12:02:58 +01:00
herman ten brugge
fadfc118e5 Fix sse calling bug 2019-10-29 07:19:42 +01:00
herman ten brugge
800c3a5e0b Add constructor/destructor support 2019-10-29 07:02:58 +01:00
herman ten brugge
c4c5ea4381 remove wine 2019-10-25 07:40:37 +02:00
herman ten brugge
b84ab23011 Add wine support 2019-10-24 22:10:04 +02:00
herman ten brugge
588dd6827a Fix elf version info 2019-10-24 20:47:02 +02:00
Pursuer2
a7b37f9c63 Fix bug in gen_cvt_ftoi1. Add test 107_stack_safe for this fix.
(Thanks to the support of herman ten brugge)
2019-10-24 00:57:59 +08:00
herman ten brugge
749dd15ee8 Fix testcase for elf version 2019-10-23 13:14:41 +02:00
herman ten brugge
66a14a1e33 Add testcase for elf_version 2019-10-22 20:45:03 +02:00
herman ten brugge
b073a9c103 Add testcase for elf_version 2019-10-22 20:43:30 +02:00
herman ten brugge
7268fe7239 Add elf version support 2019-10-22 16:55:20 +02:00
Luc Everse
491773ac58
Add error_func and error_opaque getters to libtcc 2019-10-14 09:36:14 +02:00
Jan Boon
944c4003bd Add function to list all symbols, for purpose of linking separate in-memory compilations 2019-09-16 15:24:16 +08:00
Øyvind A. Holm
c6635504fe README: Fix typo and remove trailing whitespace 2019-09-14 15:37:20 +02:00
Sergey Sushilin
53a1521c2e fix _Noreturn keyword 2019-09-08 18:35:15 +03:00
grischka
7b8799e5ff tccgen.c: local extern decls: copy s->ref for VT_PTR too
This fixes the issue

    int main() { extern char *x; }
    void main1() { extern char *x; }
    t2.c:5: error: incompatible types for redefinition of 'x'

(reported by Giovanni Mascellani 2019/07/16)
2019-09-08 16:59:17 +02:00
Sergey Sushilin
9298555eb6 add C11 stdalign.h header 2019-09-08 15:04:06 +03:00
Siddhesh Poyarekar
7d4a71fc8b arm64: Increase page size
Fedora, RHEL and Centos have a default page size of 64K for arm64, so
bump up the page size so that ELF sections of the generated inary are
correctly aligned for 64K pages too.
2019-09-03 12:39:05 +05:30
Michael Matz
9264f06efe Improve ?: expansion a little
there's no need to prematurely convert the condition into registers
before emitting the test.
2019-09-01 23:13:21 +02:00
Michael Matz
91e297acd3 riscv: Optimize compares
don't convert to 1/0 prematurely, we can save enough info
in the VT_CMP metadata to be usable for the gtst branch expansion.
2019-09-01 23:13:21 +02:00
Michael Matz
48ba22c744 riscv: Replace RR insn emitter with specific one
instead of using o() directly.  Makes the code a little easier
to read.
2019-09-01 23:13:21 +02:00
Michael Matz
d5bb407cc4 riscv: Add special cases for const operands
RISC-V supports small immediates for some operations, let's
use them.
2019-09-01 23:13:21 +02:00
Michael Matz
f8d80464a9 riscv: factor load/store code
split out common code and tidy result.
2019-09-01 23:13:21 +02:00
Michael Matz
83cf5bf17f riscv: TLC of param passing
factor and cleanup the param passing code somewhat.
2019-09-01 23:13:21 +02:00
Michael Matz
c505074a9f riscv: rewrite parameter passing
this fixes the ret_mixed_test of abitest.c, now everything of the
testsuite works.

The generic code for returns is good enough for our use, except in
the specific case of a mixed int/float structures returned in registers,
so instead of duplicating the whole generic gfunc_return function, add
another modus for gfunc_sret: returning -1 makes the actual register
transfer by a new backend function.
2019-09-01 23:13:21 +02:00
Michael Matz
9b0efa9346 riscv: Make PLT reloc be AUTO_GOT
relocs against defined symbols are replaced by relative
relocs, when a GOT slot is created.  But code relocs (usually
calls via PLT) use the plt_offset member of attr, not the got_offset
member, so the "huh" warning was triggered in the case of calls to
static functions (the code still worked).

So, for now just use the AUTO_GOT_PLT mechanism.  We could also
emit a non-PLT reloc in the backend for calls to VT_STATIC functions
(like the x86-64 backend does) and do the same as for x86-64 in
build_got_entries (which transforms PLT32 into PC32 relocs, riscv
would transform CALL_PLT into CALL relocs).  Maybe later.
2019-09-01 23:13:21 +02:00
Michael Matz
0cb6e3fff8 riscv: Fix mixed2 and mixed3 abi tests
this was caused by a simple bug, not by the current inability
to pass a {float,int} struct per psABI.  So now only ret_mixed_test
is still broken.
2019-09-01 23:13:21 +02:00
Michael Matz
98f1b83ffe riscv: Start fixing float struct passing/returnig
this fixes ret_2float_test, ret_2double_test and
ret_8plus2double_test of abitest.c.  The common gfunc_return
actually works for these cases, so let's use that for now.

The ret_mixed_test (as well as mixed2 and mixed3) are left
broken, and tccgen.c:gfunc_return can't be used for that as is,
so I'll leave the gfunc_return implementation in riscv64-gen.c for
now, I'll have to think about this some more.
2019-09-01 23:13:20 +02:00
Michael Matz
98dc4c123d riscv: Fix stdarg_many_test
if named params are passed on stack, the va_arg area begins after
that, not at sp+0.  Fixes abitest:stdarg_many_test.
2019-09-01 23:13:20 +02:00
Michael Matz
e9c2a1996a riscv: Fix tcctest.c
this is it!  With this tcctest.c works, as well as compiling
TCC with itself.  abitest.c doesn't yet work due to known
problems, all the rest does.  There are still warnings during
linking.
2019-09-01 23:13:20 +02:00
Michael Matz
509f561823 riscv: fix more sign/zero-extension problems
see the testcase.  For the signed case this problably does
the wrong thing, and it should break other archs.  Rework once
there are testcases for this.
2019-09-01 23:13:20 +02:00
Michael Matz
1ada32900b riscv: Fix ftoi and ftof(long double->float)
float to int must be truncations, not normal rounding.
And ftof was typoed to select the wrong conversion function.

This fixes tcctest.c completely.  (make -C tests test1)
2019-09-01 23:13:20 +02:00
Michael Matz
06184aec53 riscv: fix relocs for global syms
loads and stores to global symbols need to go via the
GOT (at least for weaks), otherwise -run doesn't work.
Ideally we'd generate GOT relocs (and loads) always and replace
them with PCREL relocs and adds during linking.
2019-09-01 23:13:20 +02:00
Michael Matz
69c77d1597 riscv: Fix unsigned 32bit loads
the invariant for the risc-v codegen is, that 64bit regs
generally contain the sign-extension of a 32bit value.
This wasn't heeded by loads of 32bit values from memory, which
used lwu and ultimately caused a miscompilation in string_test
of tcctest.c.

Now most of tcctest.c works (not with -run, but with linking
a real executable), except some ftoi/ftof conversions.
2019-09-01 23:13:20 +02:00
Michael Matz
2668eda595 riscv: Implement long double support
for the implementation of operations we can reuse the ones
from lib/lib-arm64.c, risc-v long double is also float128.
Also implement ggoto, and PDIV, and use t0 in load/store as
temporary register if necessary, not one given by get_reg
(the latter can destroy assignments of long double parameters
in function calls that are already set up).

This let's us compile tcc.c and tcctest.c, though both
don't yet work.
2019-09-01 23:13:20 +02:00
Michael Matz
2616c6b230 riscv: Fix 73_arm.c
some constants were loaded wrong (e.g. 0xffffabcdU), and
risc-v needs to do explicit zero-extensions for widening from
32bit (not sign-extensions like the other 64bit targets).

This makes the whole tests2.all testsuite work.

Parameter passing is still not psABI-compliant, but internally
consistent.  (e.g. structs of two floats/doubles are passed
in integer registers, but should sit in float regs).
2019-09-01 23:13:20 +02:00
Michael Matz
982de78e8d riscv: implement stdarg functions
this also fixes passing of params > 16 bytes.  In riscv
they aren't passed by value on stack, but via reference (and
because callees are allowed to modify by-ref params the caller must
allocate an own copy per call).

This fixes the stdarg parts of 73_arm.c.
2019-09-01 23:13:20 +02:00
Michael Matz
f44df9d85b riscv: some work on large function arguments
like long double (16 bytes) and structs.  Not completely
correct, but 73_arm64 somewhat works now (when the stdarg part
is disabled), though with some errors.  What's definitely incorrect
is arguments of a mixed int/float struct.  I'm using VT_LDOUBLE
(which conveniently has to be placed in a int-reg-pair) to load/store
structure arguments of size > 8 and <= 16, and that can lead to
overreads.
2019-09-01 23:13:20 +02:00
Michael Matz
ddb0c2de92 riscv: support large stack and far jumps
for 101_cleanup we need 256kb stack (with the associated problem
of needing a larger prologue/epilogue) as well as jumps out of
range for the 21bit offsets (exactly for second part of the prologue).
2019-09-01 23:13:19 +02:00
Michael Matz
b69c2ea2cf riscv: fix 90_struct-init
indirect calls were broken.
2019-09-01 23:13:19 +02:00
Michael Matz
31ecaa7c28 riscv: GOT loads, signed remainder, ELF flags
* support loading sym addresses from GOT: important for weak syms,
  fixes 104_inline.  This is still incomplete, it only works
  for taking the sym address, not for directly loading/storing into
  such symbols (i.e. not for VT_LVAL)
* another op: '%'
* ELF flags: add EF_RISCV_FLOAT_ABI_DOUBLE, which is our ABI.
2019-09-01 23:13:19 +02:00
Michael Matz
b0329ac081 riscv: predefine more macros
RISC-V uses some more control macros for features (e.g. used
int <setjmp.h> to declare the jumpbuf contents).
2019-09-01 23:13:19 +02:00
Michael Matz
5390a729d9 riscv: Implement VLA stuff
makes 78_vla_label and 79_vla_continue work.
2019-09-01 23:13:19 +02:00
Michael Matz
9164594d1f riscv: load 64bit constants, and 32bit shifts
fixes 95_bitfields.  loading 64bit constants is suboptimal
right now.  int32_t shifts really need to use the W form,
otherwise 'x << 24 >> 24' doesn't extract the low 8 bits.
2019-09-01 23:13:19 +02:00
Michael Matz
215bc1aab4 riscv: Add sar, shr insn
fixes 92_enum_bitfield.
2019-09-01 23:13:19 +02:00
Michael Matz
f64d460d29 riscv: fix 72_long_long_constant
32bit signed constants larger than 0x7ffff800 were handled wrongly.
2019-09-01 23:13:19 +02:00
Michael Matz
5fcb87138d riscv: Handle more relocs
those happen on SUSE systems.
2019-09-01 23:13:19 +02:00
Michael Matz
9309585dbe riscv: some long double support
long double on risc-v is 128bit, but there are no registers
for that type (without the Q ISA extension).  They are passed
like two 64bit integers values (with an exception for varargs,
where it's an aligned register pair).  This all requires some
hacks in generic code as otherwise RC_FLOAT regs are tried for
holding values of long double type, but we need a RC_INT register
pair.  This really could all use some cleanup for all archs.

This doesn't implement any conversions of operations for long
double, but it's enough to get 70_floating_point_literals working.
2019-09-01 23:13:19 +02:00
Michael Matz
9c1b17407f riscv: Make 32_leds work
* more ops: umod and udiv
* large immediates: suboptimal code, e.g. when loading
  0xffffffffU (which is what a cast from long to int does).

tests2 work up to 67_macro_concat.
2019-09-01 23:13:19 +02:00
Michael Matz
02c8e69a07 riscv: fp parameters
makes 23_type_coercion work.  (clean up to 31_args)
2019-09-01 23:13:19 +02:00
Michael Matz
0d3db83f16 riscv: float ops
* compares
* add/sub/mul/div
* float-float converts

makes 22_floating_point work.
2019-09-01 23:13:19 +02:00
Michael Matz
9214087259 riscv: More insns, operands and arg slots
* load/store of FP ops
* load/store from symbols, VT_LLOCAL, some with large addend
* load of VT_JMP result
* calls with many args (stack slots)
* calls with FP args
* more operations: and/or/xor/div
2019-09-01 23:13:19 +02:00
Michael Matz
b1c7520886 riscv: more insns
* register indirect loads and stores
* load of local addresses
* indirect calls (uses ra as temporary reg if necessary)
* operations *, -, <<
* gen_cvt_sxtw: is not needed in most cases, let's see

tests2 runs until (incl) 09_do_while.
2019-09-01 23:13:18 +02:00
Michael Matz
16edda58b7 riscv: Add more ops and fixes
* implement compares, gtst and gsym/gjmp and add
* implement stores (simple cases)
* fix arg passing with more than one register arg, fix
  loads to not always use 8byte loads
* add some predefined macros: __riscv, __riscv_xlen,
  __SIZEOF_POINTER__ (needed by glibc header)

The first 5 tests of tests2 run now.
2019-09-01 23:13:08 +02:00
Michael Matz
55040845f3 riscv: Handle JUMP_SLOT reloc
so that -run works.
2019-08-14 18:22:21 +02:00
Michael Matz
ef7c1a4e96 riscv: Implement some loads and calls
so that a hello world works.
2019-08-14 18:22:18 +02:00
Michael Matz
35d7b5934e riscv: hacky prolog, epilog and return
this now allows to compile a simple working example:

  int main(void) { return 0; }
2019-08-14 18:22:14 +02:00
Michael Matz
1353ccd9e2 riscv: Handle some usual relocs
this is enough to let me link a tcctest.c compiled by GCC
using some current debian sid riscv64 system.  It needs
linking against libgcc.a for various floating point TFmode
routines.  The result runs.
2019-08-14 18:19:00 +02:00
Michael Matz
0676d5bc23 riscv64: Add skeleton target 2019-08-14 18:18:46 +02:00
Michael Matz
9e429dbef0 Fix invalid size with GNU designated initializers
the uninitialized cumofs was leading to random sizes for
the memset when initializing local structures, potentially
leading to segfaults from it.  Only a problem with GNU
designated initializers, which we didn't test very well.
See testcase.
2019-07-21 21:14:58 +02:00
grischka
ce1ef5b8fc some smaller fixes
- libtcc.c/tccpp.c: fix -U option for multiple input files
- libtcc: remove decl of tcc_add_crt() for PE
- tcc.h: define __i386__ and __x86_64__ for msvc
- tcc.h: undef __attribute__ for __TINYC__ on gnu/linux platforms
- tccelf.c: disable prepare_dynamic_rel unless x86/x64
- tccpe.c: construct rather than predefine PE section flags
- tccpp.c: (alt.) fix access of dead stack variable after error/longjmp
- x86_64-gen.c: fix func_alloca chain for nocode_wanted
- tccpp.c/tccgen.c: improve file:line info for inline functions
- winapi/winnt.h: correct position for DECLSPEC_ALIGN attribute
- win32/lib/crt: simplify top exception handler (needed for signal)
- arm64-gen.c: remove dprintf left from VT_CMP commit
- tccgen.c: limit binary scan with gcase to > 8 (= smaller code)
- tccgen.c: call save_regs(4) in gen_opl for cmp-ops (see test in tcctest.c)
2019-07-14 22:46:19 +02:00
Christian Jullien
4bb5bc4401 Add Windows WSAPool declaration, associated struct and constants. It allows 100% poll compatible POSIX API on Windows. 2019-07-09 18:02:59 +02:00
YX Hao
756e766295 win: ignore dllimport/dllexport for typedef with warning instead of error
Keep the same as gcc and clang.
The usage exists in MinGW-w64 headers.
2019-07-02 18:19:24 +08:00
Christian Jullien
a4997bf3d9 Inverse last intr test so that function always returns. This prevents warning as found with gcc 8.3 and it matches other function styles doing the same in ARM generator. 2019-06-26 05:43:47 +02:00
Christian Jullien
a9340dd325 Applying grischka proposed patch fixes error reported on 93_integer_promotion test as found on Debian buster / gcc 8.3 for ARM plateform 2019-06-26 05:26:20 +02:00
Avi Halachmi (:avih)
a7eef33859 configure: conftest win32: don't translate LF to CRLF
This removes a spurious \r at $gcc_{major,minor} in configure on cygwin.

Details:

The EOL output of conftest.exe for windows was \r\n . Now it's only \n .
The output of conftest is used with sh command substitutions which trim
trailing newlines, but not all windows shells consider \r\n as newline.

E.g. msys2 and busybox (for windows) were designed for tight integration
with windows apps and their shells do trim \r\n, but cygwin sh is closer
to POSIX and trims only \n - leaving \r at the string.
2019-06-25 16:44:43 +03:00
Avi Halachmi (:avih)
84779b2b84 configure: allow cc tests even if cross compiling, test i386/x86-64
Adds a tool `ppif` at configure which can test preprocessor conditions
even when $cc is a cross compiler to any foreign platform.

Currently used only to identify i386 or x86_64 (including when cross
compiling) as a mini-demonstration.

Hopefully will be used in the future to test more compiler features
and/or replace uname-related tests with more accurate results.
2019-06-25 16:44:43 +03:00
grischka
3d78918e63 introduce scopes for VLA & attribute cleanup 2019-06-24 11:40:01 +02:00
grischka
8227db3a23 jump optimizations
This unifies VT_CMP with VT_JMP(i) by using mostly VT_CMP
with both a positive and a negative jump target list.

Such we can delay putting the non-inverted or inverted jump
until we can see which one is nore suitable (in most cases).

example:
    if (a && b || c && d)
        e = 0;

before this patch:
   a:	8b 45 fc             	mov    0xfffffffc(%ebp),%eax
   d:	83 f8 00             	cmp    $0x0,%eax
  10:	0f 84 11 00 00 00    	je     27 <main+0x27>
  16:	8b 45 f8             	mov    0xfffffff8(%ebp),%eax
  19:	83 f8 00             	cmp    $0x0,%eax
  1c:	0f 84 05 00 00 00    	je     27 <main+0x27>
  22:	e9 22 00 00 00       	jmp    49 <main+0x49>
  27:	8b 45 f4             	mov    0xfffffff4(%ebp),%eax
  2a:	83 f8 00             	cmp    $0x0,%eax
  2d:	0f 84 11 00 00 00    	je     44 <main+0x44>
  33:	8b 45 f0             	mov    0xfffffff0(%ebp),%eax
  36:	83 f8 00             	cmp    $0x0,%eax
  39:	0f 84 05 00 00 00    	je     44 <main+0x44>
  3f:	e9 05 00 00 00       	jmp    49 <main+0x49>
  44:	e9 08 00 00 00       	jmp    51 <main+0x51>
  49:	b8 00 00 00 00       	mov    $0x0,%eax
  4e:	89 45 ec             	mov    %eax,0xffffffec(%ebp)
  51:   ...

with this patch:
   a:	8b 45 fc             	mov    0xfffffffc(%ebp),%eax
   d:	83 f8 00             	cmp    $0x0,%eax
  10:	0f 84 0c 00 00 00    	je     22 <main+0x22>
  16:	8b 45 f8             	mov    0xfffffff8(%ebp),%eax
  19:	83 f8 00             	cmp    $0x0,%eax
  1c:	0f 85 18 00 00 00    	jne    3a <main+0x3a>
  22:	8b 45 f4             	mov    0xfffffff4(%ebp),%eax
  25:	83 f8 00             	cmp    $0x0,%eax
  28:	0f 84 14 00 00 00    	je     42 <main+0x42>
  2e:	8b 45 f0             	mov    0xfffffff0(%ebp),%eax
  31:	83 f8 00             	cmp    $0x0,%eax
  34:	0f 84 08 00 00 00    	je     42 <main+0x42>
  3a:	b8 00 00 00 00       	mov    $0x0,%eax
  3f:	89 45 ec             	mov    %eax,0xffffffec(%ebp)
  42:   ...
2019-06-24 11:40:01 +02:00
grischka
1b57560502 nocode, noreturn
A more automatic approach to code suppression (aka. nocode_wanted)

The simple rules are:
- Clear 'nocode_wanted' at (im/explicit) label IF it was used
- Set 'nocode_wanted' after unconditional jumps

Also in order to test this then I did add the "function might
return no value" warning, and then to make that work again I
did add the __attribute__((noreturn)).

Also moved the look ahead label check into the type parser
to gain a little speed.
2019-06-24 11:40:01 +02:00
grischka
8569048031 work on local extern declarations
Example:
    int a = 1;
    void f(void)
    {
        int a = 2;
        {
             extern int a; // = 1 !!
             ....

To get this (more) correctly there is a new function to copy
syms between local to global stacks.

Also, this patch changes the meaning of VT_EXTERN back
to the simpler and IMO more useful notion of
    DECLARED but not (yet) DEFINED.
and that for both variables and functions.  That is, VT_EXTERN
in tcc doesn't have to do with the keyword 'extern' necessarily.

Also this patch does allow
    int x[];
as alias for
    extern int x[];
(as do gcc and msvc)
2019-06-24 11:38:32 +02:00
Pascal Cuoq
cbbba01b46 reject invalid arrays in post_type() 2019-06-24 10:28:44 +02:00
Michael Matz
942b73bbbb Try fixing asm_dot_test on Windows
its GAS lacks .pushsection/.popsection and .previous, so
we must manually switch back to .text in the snippets on
that platform.
2019-06-24 05:18:08 +02:00
Avi Halachmi (:avih)
6599483304 test 104: fix out-of-tree build+test
This was broken, and now works again:
mkdir build && cd build && ../configure && make && make test
2019-06-22 09:47:57 +03:00
Michael Matz
dd60b20c6e Define __dso_handle in libtcc1.a
new glibc really can't avoid it anymore, so let's provide it.
I've tried doing it only on systems that possibly are glibc
based.  (For others it would be harmless as it simply wouldn't
be picked up from libtcc1.a)
2019-06-22 01:38:43 +02:00
Michael Matz
7894f39e65 Make VT_STRUCT_MASK unsigned
avoids a (overly anal, but correct) undefined behaviour warning
about shifting 4095 as int by 20.
2019-06-22 00:42:24 +02:00
grischka
e6d8f9a8bb test 104: adjust to (unwritten) tests2 suite conventions
... which IMO are:

1) files don't need a _test suffix because all files in
   the directory are tests ;)

2) we test the BEHAVIOR of the program, rather than its
   binary bit contents.

Ok, but nobody said a test can't use two files ;)

(where the 104+_ construct is meant to prevent the file
from being picked up by the makefile as a test on its own).
2019-06-22 00:26:31 +02:00
Avi Halachmi (:avih)
5dfcc7506c test 104: simplify, ensure sort locale, parametric tcc
Previously test 104 used a combination of *nix tools and system() calls
to emulate a `sh` script, which required split code paths for windows
due to different shell and different absolute path representation.

Also, it used a hardcoded tcc binary path, didn't set locale for sort.

Now the tools are used from a `sh` script which the program generates
and invokes, tmp files are at CWD and no conversion is required, tcc
path is taken from Makefile (exported), and `sort` uses LC_ALL=C.
2019-06-21 22:36:09 +03:00
Pascal Cuoq
944fe7036c x86-64 codegen: avoid allocating VLA of size 0 2019-06-19 20:43:10 +02:00
Christian Jullien
d39c49db2d Remove empty conditional _WIN32 code 2019-06-18 15:05:46 +02:00
Christian Jullien
d052f609fe Remove \r in win32/include/uchar.h 2019-06-18 14:39:54 +02:00
Christian Jullien
21841cb622 Add win32/include/uchar.h which is a C11 standard header. It makes Windows standalone port more C11 compliant 2019-06-18 14:38:16 +02:00
Christian Jullien
78ee3eb7c7 Add Windows support for tests of inline functions - test 104 2019-06-18 14:29:58 +02:00
Michael Matz
cb73be5346 Fix last commit
it wasn't complete.
2019-06-17 20:52:09 +02:00
Michael Matz
c3f0937012 Don't emit unreferenced static inlines
there's no need to emit unreferenced static function, even
if they are forced.
2019-06-17 19:36:59 +02:00
Michael Matz
3980e4a5b9 Add testcase for 69a46b0
that fixed mingw but also fixed the problem for which the testcase
is now added.
2019-06-17 19:08:08 +02:00
Michael Matz
fe23a14ebb Deal with more tentative definitions
see testcase.
2019-06-17 18:52:49 +02:00
Michael Matz
69a46b0c53 Make mingw work again
my last inline changes caused parameter names to be overwritten
always (as VT_EXTERN now doesn't mark the current def anymore),
leading to a compile error when including windows.h.  Rework this.

Also silence a warning that currently happens for mingw, which is
written with gnu-inline behaviour in mind.  Our work-arounds
of using "static inline" actually create invalid C (which we warn
about).  Until we implement this properly, just silence the warning.
2019-06-17 18:28:56 +02:00
Michael Matz
cb8bbf1ab9 TLC for C99 inline implementation
there's no need for two new flags in type.t .  We just can't use
VT_EXTERN as marker if functions are defined or not (like we can
for objects), and then can simply implement the rules of C99/C11
by not overwriting VT_STATIC/VT_EXTERN at all but rather only
look at them.  A function already on the inline list can be
forced by removing the VT_INLINE flag, and then linkage
follows from some combination of VT_STATIC, VT_EXTERN and VT_INLINE.
2019-06-17 03:34:03 +02:00
Michael Matz
4dfc27b101 Stricter C99 inline tests
these three functions are external definitions, and so need
to be emitted even without any references.
2019-06-17 03:33:52 +02:00
Michael Matz
7ed2d15345 Revert "Fix relocs of unwanted sections"
This reverts commit fef838db2d,
should not be necessary anymore.
2019-06-16 22:50:06 +02:00
Michael Matz
eaf5f3fa52 Ignore relocs to ignored sections as well
relocs to sections which we ignore should be ignored as well,
they have no meaning and currently would segfault.
2019-06-16 22:48:15 +02:00
Michael Matz
4c2b55f962 Fix use-after-free in tccelf.c
build_got might realloc the symbol table (for the _GLOBAL_OFFSET_TABLE_
symbol), so we can't reuse sym (a pointer into it) after build_got.
Using it isn't necessary, as we pass the sym_index to put_got_entry,
and that recomputes sym.
2019-06-16 22:06:07 +02:00
Petr Skocik
47722a8c2e fix windows errors uncovered by the inline patch
By always instantiating extern inlines, the patch has discovered
2 assembly errors, which were fixed in the original mingw64 in 2009.

This fixes those errors.

Additionally it changes __CRT_INLINE in win32/include/_mingw.h
from `extern __inline__` to `static __inline__`.

__CRT_INLINE is used exclusively in header files and as such
it should not create externally visible instantiations like a `extern
inline` would (as per the C standard).
2019-06-12 15:37:59 +02:00
Petr Skocik
587e1f5598 standard conformant inline functions
- add tests for standard conformant inline functions
- implement it

The  old tinycc failed to provide a conforming implementation
of non-static inlines.  It would expose external symbols where it
shouldn't and hide them where it should expose them.

This commit provides a hopefully comprehensive test suite
for how things should be done. The .expect file can be obtained
by compiling the example c file (embedded in the test)
with a conforming compiler such as gcc, clang or icc and then
printing the exported symbols (e.g., with nm+awk+sort).

(The implementation currently reserves two new VT_ flags.
If anyone can provide an implementation without reserving
two extra flags, please replace mine.)
2019-06-11 16:29:24 +02:00
Petr Skocik
f2fd56a27d turn -fdollars-in-identifiers on by default
gcc and clang do it too
2019-06-11 13:45:22 +02:00
Petr Skocik
60ceab1453 in c11 mode, skip __STDC_ISO_10646__
The macro conflicts (=> redef warnings in a simple hello world)
with a definition introduced by glibc headers and
it's probably not "necessary" anyway since clang doesn't use it.
2019-06-11 13:43:24 +02:00
Petr Skocik
18a2ed2936 make -h|-hh succeed if the output is successfully written 2019-06-11 12:42:26 +02:00
Michael Matz
d04ce7772c Don't allow section switches in local asm instructions
GCC wouldn't be able to implement this either (due to the separate
phases of compilation and assembly).  We could allow it but it
makes not much sense and actively can confuse broken code into
segfaulting TCC.  At least we can warn.

Warning exposes a problem in tcctest, and fixing that gives us
an opportunity to also test .pushsection/.popsection and .previous
directive support.
2019-05-30 21:31:35 +02:00
Vlad Vissoultchev
1dd6842654
Don't drop asm_label hack on external symbols for win32 DLL exports 2019-05-14 22:37:13 +03:00
matthias
cf3d23741f add tests for cleanup loop
- Also fix some gcc warning
2019-05-03 12:32:55 +02:00
matthias
14be3a1dc1 fix cleanup with for loop initialisation
Signed-off-by: matthias <uso.cosmo.ray@gmail.com>
2019-05-03 12:32:55 +02:00
matthias
0d54946dec fix cleanup with break and continue
fix cleanup
2019-05-03 12:32:55 +02:00
Michael Matz
d30bc6d00a _Static_assert must be followed by semicolon
as per the C11 grammar.
2019-05-03 00:22:35 +02:00
matthias gatto
e371642e6b _Static_assert test 2019-04-28 08:27:33 +02:00
matthias
5a0101856b add C11 _Static_assert support 2019-04-28 01:07:21 +02:00
Michael Matz
85483f321d Add 103_implicit_memmove testcase
which checks that a declaration after TCC implicitely declares
an internally used function (memmove here) doesn't create any problem.
2019-04-18 03:42:23 +02:00
Michael Matz
c07e81b087 Tidy some code
the real difference is in decl0 where we can use external_sym
just fine also for function definitions, we don't have to use
external_global_sym.  Setting VT_EXTERN in external_sym isn't
necessary either (the type will have it set if necessary).
The rest is tidying: removing unused arguments and moving
some code around.
2019-04-18 03:42:23 +02:00
Christian Jullien
f2461096b1 Add minimal includes and .def files to support, by default, BSD socket programming on Windows. 2019-04-16 07:26:04 +02:00
Michael Matz
c16dadbb97 win64: make signal handlers work somewhat
we can register a top-level exception filter which does
nothing else than call into _XcptFilter (provided by
the default C runtime environment) and signal handlers
for the few POSIX signals that Windows can handle start
working (that includes e.g. SEGV).
2019-04-15 20:02:45 +02:00
Michael Matz
105107124d Make 102_alignas independend of architecture
alignment of double is of course depending on the target,
so the .expect file was arch dependend.  Fix this by simply doing
some comparison tests.
2019-04-11 00:37:07 +02:00
Michael Matz
0344c0b6a0 Fix more struct inits
anonymous struct members were somewhat broken as the testcase
demonstrates.  The reason is the jumping through hoops to fiddle
with the offsets I once introduced to avoid having to track
a cumulative offset.  That's now not necessary anymore and actively
harmful, doing the obvious thing is now better.
2019-04-11 00:30:41 +02:00
Michael Matz
94846d3eef Some types testcases
during some rework I tripped over some more obscure but valid declarators.
Let's not loose them.
2019-04-09 04:39:38 +02:00
Michael Matz
ce4aea2478 Fix last commit's expected output
I forgot to regenerate the expected output of 102_alignas.c
just before committing and pushing :-/  This rectifies that.
2019-04-09 03:58:17 +02:00
Michael Matz
38a6aba468 Fix _Alignas
* don't accept _Alignas as type qualifier (after pointer '*').
* accept type-names within _Alignas
* add testcases
2019-04-08 22:06:51 +02:00
Ziga Lenarcic
fa0ef91a24 With -run -nostdlib use "_start" as the entry symbol. 2019-04-07 13:44:07 +02:00
Michael Matz
2a417b50ee Detect invalid VLA decls
see testcase, when the inner array dimension of multi-dimensional
VLAs isn't given TCC was generating invalid vstack accesses.
Those are actually invalid, so just diagnose them.
2019-04-07 04:09:25 +02:00
Michael Matz
5ac2a26666 Don't endlessly recurse on invalid nested typedefs
see testcase.
2019-04-07 03:15:05 +02:00
Michael Matz
d00f98a7a5 Fix 98_al_ax_extend.c compile error
this test is run only on i386 so its failing went unnoticed for
a while, since 1fd3709379.  IS_ASM_SYMs should not be tested
for conflicting types, the C typing overrides.
2019-04-07 02:44:32 +02:00
Devin Hussey
9382a3ad58 C11 conformance: Add _Noreturn, stdnoreturn.h, and partial _Alignas support
_Noreturn, just like __attribute__((noreturn)), is ignored.
I also added stdnoreturn.h, in all its glorious uselessness.

_Alignas only works for integer expressions right now. In order
to comply, we need:
 - _Alignas(type) -> _Alignas(_Alignof(type)).
 - stdalign.h as soon as it is done.

Note: DR 444 is supported; it works on struct members.

Signed-off-by: Devin Hussey <husseydevin@gmail.com>
2019-03-20 15:03:27 -04:00
Michael Matz
1fd3709379 Fix local extern vardecl
see testcases.  A local 'extern int i' declaration needs to
refer to the global declaration, not to a local one it might
be shadowing.  Doesn't seem to happen in the wild very often as
this was broken forever.
2019-03-18 05:53:03 +01:00
Michael Matz
e6980f6cc7 Detect more invalid initializers
in presence of invalid source code we can't rely on the
next token to determine if we have or haven't already parsed
an initializer element, we really have to track it in some separate
state; it's a flag, so merge it with the other two we have (size_only
and first).  Also add some syntax checks for situations which
formerly lead to vstack leaks, see the added testcases.
2019-03-18 03:31:11 +01:00
Michael Matz
d72b877e45 Fix invalid memory access in preprocess_end
when an error is thrown macro_stack might point to
unwound local variables, we can't access them.
2019-03-15 13:17:58 +01:00
Vincent Lefevre
be7c870718 Fix va_end() definition: must be an expression of type void
Also added a test yielding a failure with the previous definition,
i.e. when using: (va_end(ap));

The test also checks potentially incorrect va_start() definition.
2019-03-14 15:39:52 +01:00
Vincent Lefevre
920f773a81 Fix "make -j test"
The clean-s rule must be run before the tests, not at the same time!
2019-03-14 14:59:27 +01:00
Michael Matz
4b46e0ec63 Handle corner case for abstract decls
sometimes abstract decls in parameter lists left the returned name
uninitialized potentially leading to segfaults, like in

  int f(int ()) {
    return 0;
  }

Deal with this.
2019-03-12 17:27:15 +01:00
Michael Matz
ef0397cf3d Fix crash on invalid code
like on 'enum myenum { L = -1 } L;'.  It's a bit tedious as
there are two paths (for global vs local symbols), and because
the scope and enum_val share same storage.
2019-03-08 17:58:25 +01:00
matthias
b082659f19 fix segv in "{,}" combound literal 2019-03-06 18:51:13 +01:00
Michael Matz
fef838db2d Fix relocs of unwanted sections
relocation sections to sections we don't want to handle lead
to segfaults, handle this situation (by ignoring the relocs
as well).
2019-03-04 16:53:24 +01:00
Michael Matz
749d19d70b Fix sub-int returns on x86-64 and i386
the ABIs (and other compilers) extend sub-int return values in the
caller.  TCC extends them in the callee.  For compatibility with
those other compilers we have extend them in the caller as well.
That introduces a useless double extension in pure TCC-compiled code,
but fixing that generally requires that the code generator of TCC would
understand sub-int types.  For the time being bite the bullet.
2019-02-10 18:27:41 +01:00
Michael Matz
5f737fb4d3 tidy code 2019-01-31 01:04:55 +01:00
Michael Matz
5c862a08b4 suppress code after continue as well
fix an oversight in code suppression
2019-01-31 00:37:49 +01:00
matthias
d27ea5155f remove incr/decr_local_scope functions 2019-01-29 21:32:38 +01:00
Michael Matz
08e22d8ad2 More cleanup tests
test3 wasn't working originally.
2019-01-28 05:54:19 +01:00
Michael Matz
4cc802a88e Tidy new support for cleanups
encode most things in Syms, do only as much work as necessary
(e.g. pending cleanups), don't track scopes in a large
structure (instead encode the scopes with cleanups directly
in the cleanups tree).  Removes ca. 120 lines of code.
2019-01-28 05:54:19 +01:00
Detlef Riekenberg
5d805a90e3 tcc.c: Fix outdated help info for the std option
the std option is no longer ignored

--
bye bye ... Detlef

Signed-off-by: Detlef Riekenberg <tcc.dev@web.de>
2019-01-27 17:32:11 +01:00
matthias
46145af4a1 remove C99 'for' loop initial declarations 2019-01-23 19:42:04 +01:00
matthias
5010023428 remove outdated comment 2019-01-23 17:21:14 +01:00
matthias
de92fbee7e add a cleanup test that use a lot of scope 2019-01-23 17:21:14 +01:00
matthias
26f0cf0708 Fix scope limit for cleanup attribute
old implementation use only a global static array for storing
ScopeTracker which have the advantage to be fast, but you can't
use cleanup in a function that have move than SCOPE_TCK_STORE_SIZE
scopes.

I don't want to use only dynarray_* as it would slow down tcc for
every functions, so I keep both stores.
2019-01-23 17:21:14 +01:00
matthias
ff38d90d5d Add attribute cleanup test 2019-01-23 17:21:14 +01:00
matthias
0d91ba749c Add gcc attribute cleanup support
The major difficulty was to handle cleanup when a goto happen
to do so, I've had a "ScopeTracker" struct.
I can't use local_scope because that would not work with code like below
as local_scope would be at the same level:

{
    char * __attribute__ ((cleanup(clean_function))) str = "hej";
    goto next;
}
{
    next:
}
2019-01-23 17:21:14 +01:00
Giovanni Mascellani
f6be0d483b
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.
2019-01-13 15:20:39 +01:00
Christian Jullien
acac38afb2 Add C99 compiliant iso646.h header 2019-01-13 10:24:50 +01:00
Michael Matz
45b8b0e57d Revert 337dc84b (other -static fix)
this should work now with 05f6aa1a.
2019-01-13 06:01:59 +01:00
Michael Matz
05f6aa1ade Fix -static linking with uClibc
symbols are local when defined and referred to from the executable.
Also, we need to relocate the .got section when this is a static link
(our static linking effectively generates code as if this were a dynamic
link with PLT and GOT, and then emulates the runtime loader).
2019-01-13 06:00:51 +01:00
Michael Matz
adbe794a46 Properly access sym_attrs
in corner cases the direct access to the sym_attrs[] array in the
backends is out of bounds and replacec garbage symindices into
the relocs.
2019-01-13 02:55:44 +01:00
Christian Jullien
d44d8cdf60 Add more STDC_ C11 compatible constants 2019-01-12 10:41:56 +01:00
Pursuer
ecb90de4cc FIX:Revert commit 3f05d88d5b
The function should to be saved to stack in some cases (fastcall on i386, struct argument on arm etc.). But I neglected. So I revert this commit.
2019-01-12 01:54:24 +08:00
Christian Jullien
8482f9e54b Add __STDC_xxx test features related to ISO/IEC C11 when -std=c11 is passed. 2019-01-11 14:26:17 +01:00
Petr Skocik
065a3b35fc Make stddef.h expose max_align_t with -std= >= c11 2019-01-11 11:17:49 +01:00
Matthias Gatto
2b94c0c3b1 Revert "allow c11 feature only when -std=c11 is use"
This reverts commit 756988e8f9.
2019-01-11 10:35:44 +01:00
matthias gatto
756988e8f9 allow c11 feature only when -std=c11 is use 2019-01-10 23:42:45 +01:00
Christian Jullien
a3a291784a Add -std=c11 option which sets __STDC_VERSION__ to 201112L and allows to implement c11 features conditionally 2019-01-11 02:32:48 +08:00
Kurt Nalty
337dc84b57 Fixed -static linking on x86_64 Linux 2019-01-11 02:32:48 +08:00
Petr Skocik
51f6e52dd3 Support multiple __label__ declarations
Support multiple __label__ declarations at the beginning of a block
as long as they're contiguous.

gcc and clang accept:
    { __label__ a,b; __label__ c;  /*...*/ }
.
Tcc would fail it. This patch makes it accept it.

The patch:
-        if (tok == TOK_LABEL) {
+        while (tok == TOK_LABEL) {
2019-01-11 02:32:47 +08:00
Pursuer
3f05d88d5b optimize the generated code when save_reg is required (2)
In gfunc_call, regisger will be saved before gcall_or_jmp. The register
stored the function will be saved too, though in some generator the SValue
of this function will be immediately poped after gcall_or_jmp, and no need to be saved. So I modify some generator to avoid save redundant SValue before gcall_or_jmp.
2019-01-11 02:32:12 +08:00
Pursuer
b3b685d92a optimize the generated code when save_reg is required
Before this patch, save_reg can't reuse the temporary local variable
created before to save register. It may consume a lot of stack memory. this patch make save_reg reuse the temporary local variable.
2019-01-10 13:17:14 +08:00
Pursuer
0c313f491b Insert arm-xxx_FILES into Makefile to suport CROSS_TARGET and Remove duplicate function lexpand_nr 2019-01-09 02:06:26 +08:00
Petr Skocik
7369cfc490 Revert "Add max_align_t to stddef.h"
max_align_t is C11 not C99 and the name is not reserved by C99.

This reverts commit 7eceba178d.
2019-01-08 12:32:18 +01:00
Petr Skocik
7eceba178d Add max_align_t to stddef.h 2019-01-04 14:56:37 +01:00
Christian Jullien
f21b53b5ed Add winnls.h to allow SQLite compile ROOTB on Windows 2019-01-01 08:58:09 +01:00
Michael Matz
3e007193a2 Fix more attribute placements
when parsing the type in this cast:
  (int (__attribute__(X) *)(int))foo
we ignored the attribute, which matters if it's e.g. a 'stdcall'
attribute on the function pointer.  Only this particular placement
was misparsed.  Putting the attribute after the '*' or outside the inner
parens worked.  This idiom seems to be used on SQLite, perhaps this
fixes a compilation problem on win32 with that.
2018-12-31 22:00:31 +01:00
Christian Jullien
325241c0de zfunc works again on ARM after Pursuer fix 2018-12-22 19:14:22 +01:00
general
bf09349f8e fix arm-gen.c -> gcall_or_jmp to VT_CONST 2018-12-22 19:48:56 +08:00
Theodore Dubois
82abfd75f3 Fix ELF interpreter of i386 musl target 2018-12-22 04:29:06 +00:00
Michael Matz
63f69c2bdd Disable -Wformat-truncation
this new gcc 8 warning triggers here, but is useless for our
purposes.
2018-12-21 01:03:38 +01:00
Michael Matz
f68a1f50fd Don't use C99 decls
we're consciously trying to write C90 compatible code, hence
no mixed declaration and code.
2018-12-21 01:03:05 +01:00
Christian Jullien
adfcf3b1dd Temporary remove zfunc test on ARM which generates a relocation error. Waiting for a fix 2018-12-20 08:44:47 +01:00
Christian Jullien
8494f2c318 Fix Thomas commit 776aa0c093 which failedto build on Windows. 2018-12-17 17:05:05 +01:00
Petr Skocik
070646b790 Recognize C11' _Alignof 2018-12-12 20:12:03 +01:00
Michael Matz
c4787e3626 Fix type completion for array types as well
like qualifier merging the array sizes are merged as well
for the operands of ?:, and they must not statically influence
the types of decls.

Also fix some style problems, spaces aren't stinky :)
2018-11-30 23:43:30 +01:00
Petr Skocik
f7779efe58 Fix incorrect one-sided void handling in ?:
Also make the case when one side in ?: is a ptr
and the other is neither a ptr nor a null-ptr constant
fail cleanly instead of segfaulting.
2018-11-29 13:40:48 +01:00
Petr Skocik
49dfb5755a Make fn designators in ?: decay to ptrs
This
    _Generic((__typeof(1?f:f)*){0}, void (**)(void): (void)0);
should compile like it does in gcc and clang.
2018-11-29 12:43:01 +01:00
Petr Skocik
3058d4116e Fix (Cexpr?struct1:struct2).member
Tcc used to fail this with `lvalue expected`
if the expression was a compile-time constant.
2018-11-29 10:26:56 +01:00
Petr Skocik
9d44b02a49 Fix the fix on type combining (e0012c2)
char **argv;
	    _Generic(argv, char**: (void)0);
	    _Generic(0?(char const*)0:argv[0], char const*: (void)0);
	    _Generic(argv, char**: (void)0);

    would fail because the type of argv would get modified by the
    ternary. Now allocate a separate type on the value stack to
    prevent this error.
2018-11-29 10:26:35 +01:00
Petr Skocik
e0012c2767 Fix ptr type combining inside the ternary operator
Make it match http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6
(or http://port70.net/~nsz/c/c11/n1570.html#6.5.15p6).
2018-11-28 10:36:58 +01:00
Petr Skocik
c81116e29a Make casts lose top-level qualifiers
TODO: also make them lose lvalue status
2018-11-20 19:24:24 +01:00
Petr Skocik
f85b1e393f Always allow ({ }) in the ctrl-expr of _Generic
tcc would reject e.g.,
    void f(){ struct {_Bool x:_Generic(({0;}),default:1);} my_x; }
with `expected constant`. This patch makes it accept it.

(The patch also makes tcc's _Generic a little more "generic" than that
 of gcc and clang in that that tcc now also accepts
`struct {_Bool x:_Generic(({0;}),default:1);} my_x;` in file scope
while gcc and clang don't, but I think there's no harm in that
and gcc and clang might as well accept it in filescope too, given
that they have no problem with
e.g., `/*filescope:*/int x=1, y=2, z=_Generic(x+y, int:3);`)
2018-11-13 12:51:16 +01:00
Petr Skocik
1e2e5671f7 Make tcc accept -l lib as well as -llib.
The POSIX spec for `c99` specifically favors the space-containing version
(http://pubs.opengroup.org/onlinepubs/9699919799/utilities/c99.html)
and the `-l lib` syntax is also supported by gcc and clang.
2018-11-12 20:52:53 +01:00
Petr Skocik
314843ffc3 Fix how _Generic treats pointers to arrays.
_Generic should distinguish pointers to differently sized
arrays such as `int(*)[2]` and `int(*)[4]`.
2018-11-12 20:52:14 +01:00
Petr Skocik
73ca09ff32 Fix array pointer stringification.
`int (*)[4];` should not be stringified as `int *[4];`
Add stringification tests.
2018-11-12 20:50:51 +01:00
Petr Skocik
93a4ddfa63 Treat the - output as stdout. 2018-11-12 20:50:33 +01:00
Michael Matz
3b9c3fd186 Fix noreturn in main()
ISO C requires 'main' falling through the end without explicit
returns to implicitely return 0 (if declared as returning int).
2018-11-03 22:17:20 +01:00
Michael Matz
61ba9f2299 Check for void type in top-level decls
give an error message from the parser on things like "void x;" instead
of relying on codegen erroring out.
2018-08-03 22:51:35 +02:00
Michael Matz
22420ee1ee Fix misparsed type in presence of attributes
The type within the cast (int (__attribute__((foo)) *)(void))
was misparsed because of the presence of the attribute (parse_btype
prematurely concluded that (__attribute__() *) is a type.

Also see testcase.  This construct is used in sqlite it seems.
2018-07-28 18:55:54 +02:00
Jonathan Newman
0edbed1d52 Implement __attribute__((nodecorate))
Prevent any decoration that would otherwise affect an exported
PE function. For example, given the following:

__declspec(dllexport) __stdcall
int decorated(int arg) {
    return 0;
}

__declspec(dllexport) __stdcall __attribute__((nodecorate))
int undecorated(int arg) {
    return 0;
}

The following exported functions can now be seen in the DLL:
_decorated@4
undecorated

The attribute is recognised for all targets but only
affects PE codegen. I'm not sure whether this would be
useful for other targets; its intended use was to allow
the creation of a DLL matching an existing set of signatures.
2018-07-22 00:54:01 +01:00
Michael Matz
d79caa9ff6 x86-64: Fix calls via absolute function pointers
linkers don't treat relocations using symindex 0 (undefined)
very well, it can't be misused as indicator for an absolute number.
Just don't bother with special casing this, rather emit an indirect
call/jump right away. ARM64 needs the same (and didn't handle
calls via constant absolute func pointers before).

The testcase as is doesn't fail without the patch, it actually
needs separate compilation (to -fPIC .o file, then to shared lib)
to fail.
2018-07-02 01:57:29 +02:00
Michael Matz
65c7f19deb Fix stored type of arguments on x86-64
the lvalue Syms for arguments didn't correctly reflect
their own types in all cases (a side-effect of the type being
stored in type->t and the ->r members (as VT_LVAL_xxx), so the below
used an int load (not a byte load) in the conditional.

extern void bar (void);
void foo (signed char c)
{
  signed char x = c;
  if (c)
    bar();
}
2018-06-24 20:12:51 +02:00
Andrey Gursky
91bdb5a4a3 Add linker's --export-dynamic flag alias
Since 9336fa7ae5 --export-dynamic is
supported. Add this conventional flag as alias.
2018-06-11 18:26:04 +02:00
grischka
8f6fcb709a misc fixes
misc fixes including:
- tcc.c: fix "tcc -vv" for libtcc1.a on win32/PE
- tccelf.c: fix a crash when GOT has no relocs (witn -nostdlib)
- tccelf.c: fix stab linkage for zero n_strx
- tccgen.c: fix stdcall decoration for array parameters
    int __stdcall func(char buf[10]) is _func@4 (was _func@12)
- tccgen.c: fix static variables with nocode/nodata_wanted
    see tests2/96_nodata_wanted.c
- tccrun.c: align sections using sh_addralign (for reliable function_alignment)
- tests2/Makefile sort 100 after 99
- win32/include/sys/stat.h fix _stat and _wstat
- x86_64-gen.c: win64/gfunc_call: fix a bug with xmmN register args
    previously overwrote valid other xmmN registers eventually
2018-06-01 12:52:01 +02:00
grischka
2b155a8c16 tccgen.c: fix warning for incompatible struct- and function pointers
see tests2/60_errors_and_warnings.c
2018-06-01 12:41:21 +02:00
grischka
ace1225492 tcc_add_file(): preserve s->filetype
This is supposed to fix a bug where libtcc eventually was trying to
compile libtcc1.a as C source code.

Anyway, there is now only two functions that refer to s->filetype,
tcc_add_file() and tcc_add_library().
2018-06-01 12:41:17 +02:00
Michael Matz
671dcace82 Implement function alignment via attributes
which requires being able to emit an arbitrary number of NOP
instructions, which is also implemented here.  For x86 we
could emit other sequences but these are the easiest.
2018-04-06 23:02:42 +02:00
Petr Skocik
ef668aae1e Don't fail on const/restrict/static/* inside []
This patch makes tcc ignore them.

Normally (as per the C standard), They should
be only applicable inside parameter arrays
and affect (const/restrict) the pointer the
array gets converted to.

[matz: fix formatting, add volatile handling, add testcase,
add comment about above deficiency]
2018-04-01 00:48:09 +02:00
Petr Skocik
d6d3cf00ec patch type_to_str to handle complex function-ptr decls better
Code like:

    #include <signal.h>
    int main() { _Generic(signal, int: 0); }

should fail with
    error: type 'extern void (*(int, void (*)(int)))(int)' does not match any association
not
    error: type 'extern void *(int)(int, void *(int))' does not match any association

[matz: fix formatting, fix function-to-pointer decay for operands of
_Generic, add testcase for this]
2018-04-01 00:38:11 +02:00
Michael Matz
f0a25ca263 Fix shortening casts of long long
see added testcase.
2018-03-31 21:52:20 +02:00
Thomas Preud'homme
c41caac02d Select VFP if triplet is arm-linux-gnueabihf
A target triplet of arm-linux-gnueabihf indicates that the compiler
should use the VFP variant of the calling convention which as its name
implies requires VFP. This commit enables VFP when triplet is
arm-linux-gnueabihf.
2018-03-15 23:05:25 +00:00
Thomas Preud'homme
e76058c478 Remove asm-c-connect-sep in tests clean target 2018-03-09 20:10:36 +00:00
Thomas Preud'homme
776aa0c093 Prevent dead code on !x86 in prepare_dynamic_rel
In prepare_dynamic_rel() on non x86 targets the count++ statements
appear before any case label and are therefore dead code. This triggers
build failure when building with -Werror. This patch adds an extra guard
around all the x86 case labels and their associated action, leaving just
the default case label for non x86 targets which builds fine.

Origin: vendor
Forwarded: no
Last-Updated: 2018-02-24
2018-02-24 19:35:15 +00:00
Michael Matz
3e6515b64f Add make testspp.all/testspp.20
like we have already make tests2.XX.
2018-01-05 02:19:26 +01:00
Michael Matz
7ad2cf8d68 Code suppression fixes
See adjusted testcase, a lone break; in a do while loop was
incorrectly disabling the exit test.
2018-01-05 02:19:26 +01:00
Michael Matz
8294285d8f Don't emit applied .rel sections
for a final link we shouldn't emit relocation sections that are applied
already.  For now we need to emit ALLOCed .rel sections as they contain
dynamic relocs, they should be put into their own (new) section instead.
2018-01-01 05:29:46 +01:00
foobar
988e2ff7fe fix debug info with musl on x86_64
http://lists.nongnu.org/archive/html/tinycc-devel/2017-12/msg00031.html
2017-12-28 15:05:27 +00:00
Michael Matz
414b224efa Accept more floating point constant expressions
the rules for constant expressions in static initializers are more
relaxed than for integer constant expressions.  We need to accept
0.0/0.0 in static initializers (in non-static initializers the potential
exceptions need to be raised though, so no translation-time calculation
then).
2017-12-25 12:44:29 +01:00
Michael Matz
9e47b18229 Make type of __nan__ __inf__ and __snan__ be float
so that those builtins can be used directly for the C99 NAN and
INFINITY math.h macros.
2017-12-24 13:16:09 +01:00
Michael Matz
3b27b3b1d1 Fix -pthread in a different way 2017-12-23 14:49:07 +01:00
Michael Matz
1b1b270f1e Revert "Fix -pthread option handling"
This reverts commit 3f8225509b.
It fixes the linking case but introduces an ugly error with -c
about adding a library.  To fix both uses the old code structure is
better.
2017-12-23 14:46:27 +01:00
Michael Matz
3f8225509b Fix -pthread option handling
adding -pthread confused option parsing as the number of file counting
came out wrong.  Simplify and fit it, can be handled purely within
option parsing, no need for a state flag.
2017-12-23 14:14:57 +01:00
grischka
d348a9a51d final update for 0.9.27
tccgen.c:
- fix ldouble asm hack
- fix a VLA problem on Win64 (also x86_64-gen.c)
- patch_type(): make sure that no symbol ever changes
  from global to static

tcc.c:
- tcc -vv: print libtcc1.a path also on win32

tccpe.c, tcctools.c:
- use unix LF mode to for .def output files (that is for
  creating reproducible output trees)

Makefile:
- suppress some warnings when makeinfo is missing
- call 'which install' only on win32

tests/Makefile:
- change PATH only on WINNT systems (i.e. not if cross-compiling
  on linux for win32)
- asm-c-connect.test: slim output and do diff

tccrun.c tccpe.c *-link.c:
- integrate former 'pe_relocate_rva()' into normal relocation
  This also fixes linkage of the unwind data on WIN64 for -run
  (reported by Janus Lynggaard Thorborg)

tccasm.c, tests/tcctest.c:
- fix dot (sym_index of -1 crashed in put_elf_reloc)
- massage .set a bit (see test)

other:
- #define SECTION_ABS removed
- ST_DATA Section *strtab_section: removed
- put_extern_sym2(): take int section number

Conflicts:
	tccelf.c
	tccpe.c

Conflicts:
	tccelf.c
2017-12-12 17:57:20 +01:00
grischka
1a4d4b76e8 tccgen_begin/end_file
This is supposed to make compilation and linking with
multiple source files (tcc f1.c f2.S ...) behave just
the same as linking object files.

tccgen.c:put_extern_sym2():
- use put_elf_sym to enter new symbols unconditionally

tccelf.c:
- save section state before compilation
- disable symbol hashing during compilation
- merge symbols and update relocations after compilation

tccpe.c:
- re-create s1->uw_sym for each compilation (because it
  may change)
2017-12-12 17:33:37 +01:00
Michael Matz
8490c54dbd Fix some multi-file corner cases with asm
for this we have to create also asm symbols as VT_STATIC initially
except if there's an indication that it should be global (.globl
or undefined at end of unit).  For this to work we need to
be able to globalize symbols after they were local and enter them
into the ELF hash tables, and also adjust the symbols that were
potentially already used in relocs when they were still local.

The easiest is to do a proper symbol resolution step also in multi-file
mode, for regular symbols (the non-dynamic ones, i.e. not from shared
libs).
2017-12-10 06:50:58 +01:00
grischka
3ae1a2af1c tccgen: unify type redefinition checks
tccgen.c:
- improved function patch_storage() and added new function
  patch_type() for more consistent type redefinition and
  instance redefinition checks.
2017-12-05 02:06:26 +01:00
grischka
877e164d6a tccasm: use global(_symbol)_stack
* removed asm_label stack
* removed asm_free_labels() post-processing
* using "impossible C type" for asm labels (VT_ASM)
* tccgen.c:update_storage(): use it to refresh symbol attributes
* tccelf.c:find_elf_sym(): ignore STB_LOCAL symbols
* tccgen.c:unary(): asm symbols are supposed to be undeclared in C
2017-12-05 01:54:49 +01:00
Michael Matz
cc6cb7f0e2 Fix another corner case with C/asm symtable
See testcase (from grischka).  If the asm has no .globl,
but there's a (non-static) C definition the symbol should
be exported, even if the first reference comes from asm.
2017-12-04 03:51:14 +01:00
Michael Matz
529b44c0d5 tccasm: Accept suffixed cmovCC
The length suffix for cmovCC isn't necessary as the required register
operands always allow length deduction.  But let's be nice to users
and accept them anyway.  Do that without blowing up tables, which means
we don't detect invalid suffixes for the given operands, but so be it.
2017-12-03 04:53:50 +01:00
Michael Matz
9e0d23cc47 tccasm: Unify C and asm symbol table
This makes the asm symbols use the same members as the C symbols
for global decls, e.g. using the ELF symbol to hold offset and
section.  That allows us to use only one symbol table for C and
asm symbols and to get rid of hacks to synch between them.

We still need some special handling for symbols that come purely
from asm sources.
2017-11-27 04:59:29 +01:00
Michael Matz
3494e5de3a Adjust asm-c-connect testcase for Windows
Calling conventions are different, let's use functions without
any arguments.
2017-11-27 01:09:50 +01:00
Michael Matz
4266ebd69c tccasm: Don't abuse dllexport/dllimport
For tracking if asm symbols are connected with a C symbol,
and if asm symbols need to be global use new flags, instead of
reusing dllimport/dllexport, which would cause unrequested exported
entries on Windows.

This is a stop-gap until the C and asm symtable are unified.
2017-11-25 19:41:03 +01:00
Michael Matz
e7c71e2473 tccasm: synch C and asm symtab tighter
See testcase.  The C and asm symtab are still separate,
but integrated tighter: the asm labels are only synched at file
end, not after each asm snippet (this fixes references from one
to another asm block), the C and asm syms are synched both ways,
so defining things in asm and refering from C, or the other way
around works.  In effect this model reflects what happens with
GCC better.

For this the asm labels aren't using the C label namespace anymore,
but their own, which increases the size of each TokenSym by a pointer.
2017-11-22 17:57:43 +01:00
Michael Matz
330c01bfc6 Adjust testcase for PIE compilers
one some systems GCC defaults to PIC/PIE code which is incompatible
with a unannotated asm call to a function (getenv here).  TCC doesn't
support these PIC annotations (yet), so play some pre-processor games.
2017-11-19 15:36:47 +01:00
Michael Matz
d0db21757a Fix forward asm labels differently
while last change fixed one part of label behaviour (undefined ones
must be global) it again broke a different aspect (forward defs
without .globl must stay local).  This fixes both aspects.
That a label is local instead of global is difficult to test without
resorting to look at the symbol table or using two-file testcases,
so we do without.  In essence the local/global-ness of symbols
should be the same between GAS and TCC for this input:

    .globl glob1
    glob1:
    call glob1

    .globl glob2
    call glob2
    glob2:

    glob3:
    .globl glob3
    call glob3

    glob4:
    call glob4
    .globl glob4

    call glob5
    .globl glob5
    glob5:

    call glob6
    glob6:
    .globl glob6

    locl1:
    call locl1

    call locl2
    locl2:

    unref1:
    unref2:
    .globl unref2
    .globl unref3
    unref3:
    call undef
2017-11-19 03:04:11 +01:00
Michael Matz
a8ece0f2ce Don't make forard asm symbols static by default
fixes the problem in the testcase.  A symbolic reference
from asm, which remains undefined at the end of processing is
always a global reference, not a static (STB_LOCAL) one.
This also affected the linux kernel.
2017-11-16 13:29:59 +01:00
Michael Matz
348dd9f4a6 Fix absolute memory references
This properly fixes what 870271ea tried to fix.  Absolute memory
references can't use %rip relative addressing, and additionally,
if the address doesn't fit 32bit (signed) it must be loaded via
movabs.  No good testcase added, it would require catching signals
and still be unreliable.
2017-11-15 13:39:28 +01:00
Michael Matz
74463eb954 Revert "gen_addrpc32: absolute ptr needs *ABS* relocation"
This reverts commit 870271ea07.

The commit is broken, you can't unconditionally emit a PC-relative
relocation without a symbol.  And if there's a symbol the addend
need to be in the relocation, not the section.
2017-11-14 16:43:22 +01:00
janus.lt
32c9b51401 Win64/PE: Changed runtime function unwind info to be added after relocation, fixes SEH + long jmps 2017-11-04 00:18:37 +01:00
emekoi
fc0188ffbc fixed dylib typo in libtcc.c 2017-10-19 00:55:42 -05:00
grischka
da8c62f75d various stuff
win32/Makefile ("for cygwin") removed
- On cygwin, the normal ./configure && make can be used with either
  cygwin's "GCC for Win32 Toolchain"
      ./configure --cross-prefix=i686-w64-mingw32-
  or with an existing tcc:
      ./configure --cc=<old-tccdir>/tcc.exe

tcctest.c:
- exclude test_high_clobbers() on _WIN64 (does not work)

tests2/95_bitfield.c:
- use 'signed char' for ARM (where default 'char' is unsigned)

tests:
- remove -I "expr" diff option to allow tests with
  busybox-diff.

libtcc.c, tcc.c:
- removed -iwithprefix option.  It is supposed to be
  combined with -iprefix which we don't have either.

tccgen.c:
- fix assignments and return of 'void', as in
     void f() {
         void *p, *q;
         *p = *q:
         return *p;
     }
  This appears to be allowed but should do nothing.

tcc.h, libtcc.c, tccpp.c:
- Revert "Introduce VIP sysinclude paths which are always searched first"
  This reverts commit 1d5e386b0a.

  The patch was giving tcc's system includes priority over -I which
  is not how it should be.

tccelf.c:
- add DT_TEXTREL tag only if text relocations are actually
  used (which is likely not the case on x86_64)
- prepare_dynamic_rel(): avoid relocation of unresolved
  (weak) symbols

tccrun.c:
- for HAVE_SELINUX, use two mappings to the same (real) file.
  (it was so once except the RX mapping wasn't used at all).

tccpe.c:
- fix relocation constant used for x86_64 (by Andrei E. Warentin)
- #ifndef _WIN32 do "chmod 755 ..." to get runnable exes on cygwin.

tccasm.c:
- keep forward asm labels static, otherwise they will endup
  in dynsym eventually.

configure, Makefile:
- mingw32: respect ./configure options --bindir --docdir --libdir
- allow overriding tcc when building libtcc1.a and libtcc.def with
      make XTCC=<tcc program to use>
- use $(wildcard ...) for install to allow installing just
  a cross compiler for example
      make cross-arm
      make install
- use name <target>-libtcc1.a

build-tcc.bat:
- add  options: -clean, -b bindir
2017-10-11 18:13:43 +02:00
YX Hao
faa9744f5d Win: crt, initialize global __argc, __targv and _tenviron of msvcrt
_tenviron: as far as possible, not in ASC '-run' mode.
__argc and __targv are shortcuts for _tWinMain, when you want to use program parameters.
2017-10-10 20:39:05 +08:00
Steffen Nurpmeso
6f1860e200 Fix Windows++ compilation of previous (YX Hao, Joel Bodenmann) 2017-10-09 14:52:56 +02:00
Steffen Nurpmeso
1d5e386b0a Introduce VIP sysinclude paths which are always searched first 2017-10-03 17:58:45 +02:00
Steffen Nurpmeso
a1c9051313 Adjust va_list to work with musl 2017-09-30 16:11:54 +02:00
Christian Jullien
2e5751caf1 tools directory no more exists, removed in win32 tarball Makefile target. 2017-09-29 07:26:21 +02:00
Larry Doolittle
8deb05c3e2 Use more conventional punctuation for sequential assignments 2017-09-25 22:16:23 -07:00
Avi Halachmi (:avih)
abd1532ad4 freebsd: allow building tcc which targets windows
Currently tcc doesn't have a compile-time config indicating that the target
is freebsd, and as a result, the tcc binary adds freebsh stuff to elf headers
if the compile-time (of tcc) *host* is freebsd.

Test also that the target is not PE while generating an elf header.

This still likely fails (but untested) when tcc targets other non-freebsd
systems on a freebsd system, but for now fix it only when targetting windows.
2017-09-25 18:39:35 +03:00
Larry Doolittle
560188711d Fix some spelling in documentation 2017-09-24 18:22:42 -07:00
Larry Doolittle
1b6806e5bb Spelling fixes
Comments only, no change to functionality
2017-09-24 18:03:26 -07:00
Larry Doolittle
44d4da62bb Convert two .c files to LF line endings
... matching the other 157 .c files in the tree
2017-09-24 16:48:08 -07:00
grischka
1443039416 'long' review
add some features for more complete 'long' support

tcc.h:
- use LONG_SIZE=4/8 instead of TCC_LONG_ARE_64_BIT
tccgen.c:
- add ptrdiff_type, update size_type
- support shift and ?: operations
- support long enum types
- display 'long' from type_to_str
- nwchar_t is unsigned short on windows
- unrelated: use memcpy in init_putv for long doubles to avoid
  random bytes in the image (if tcc was compiled by gcc) for
  diff purposes.
tccpp.c:
- make parse_number return correct types
- improve multi-character-constants 'XX' 'abcd'
Changelog:
- update
2017-09-24 18:57:48 +02:00
Zdenek Pavlas
870271ea07 gen_addrpc32: absolute ptr needs *ABS* relocation
Dereferencing of absolute pointers is broken on x86_64, eg:

*(int*)NULL does not segfault but returns -4 instead
*(char*)(-10L << 20) does not return 0x55 (vsyscall page, push rbp)
2017-09-11 06:36:16 -07:00
Zhang Boyang
078d8c2c5a Add test case for fastcall calling convention 2017-09-10 18:22:48 +08:00
Zhang Boyang
f406f63a38 Add test case for AL/AX extending problem 2017-09-10 17:03:34 +08:00
Zhang Boyang
978d1ecce0 Add test case for wide char handling in wide string literal 2017-09-10 16:50:19 +08:00
Zhang Boyang
b39810ff78 Fix calling function pointers casted from intergers in DLL
The code generated for "((void (*)(void))0x12345678)()" will be a single "CALL 0x12345678" in previous code.
However, this will not work for DLLs, because "CALL imm" is PC related, DLL relocation will break the code.
This commit fixed the problem by forcing TCC generates indirect CALLs in this situation.
2017-09-09 21:11:56 +08:00
Zhang Boyang
02370acdc9 Fix AL/AX is not extended to EAX when calling indirectly
AL/AX should be extended to EAX when calling functions. However, the previous code did this only for direct calls, indirect calls were ignored.
New code also avoid redundant code when generating JMP instruction. (i.e. expanding code should be generated with CALL instruction only)
2017-09-09 21:01:42 +08:00
Zhang Boyang
a82c11f4b4 Fix wide char handling in wide string literal
This commit fixed the problem that TCC directly cast each byte in wide string literal to wchar_t, which is wrong when wide string literal contains real wide chars.
It fixed the problem by assuming input charset is UTF-8, and wchar_t stores wide chars in UTF-16 (Windows) or UTF-32 (others).
The UTF-8 decoder is coded according to The Unicode Standard Version 10.
2017-09-09 20:37:43 +08:00
Zhang Boyang
b8fe8fc210 called function should pop the arguments when using fastcall 2017-08-21 19:38:11 +08:00
Edmund Grimley Evans
ac41e015f1 Convert from ISO-8859-1 to UTF-8. See aa812e8. 2017-07-26 13:07:14 +01:00
Matthias Gatto
4f15d08ea1 Revert "use int for ssize_t, (u)intptr_t instead of long in stddef.h"
This reverts commit 52622c3c03.

Because 28b7c9 was right.
2017-07-26 10:25:52 +02:00
matthias
c18fc950d7 Revert "simplify VT_LONG parsing"
Too simple long parsion.
Take me a long long long time to see my mistake,
Sorry

(long long long wasn't see as an error)
This reverts commit a4cd2805f9.
2017-07-25 22:04:24 +02:00
Christian Jullien
023d4e0b59 Remove debug echo in Cygwin Makefile 2017-07-25 19:17:10 +02:00
Christian Jullien
421a1c48bb Update Cygwin Makefile to use -B. for bootstrap 2017-07-25 19:12:04 +02:00
Matthias Gatto
52622c3c03 use int for ssize_t, (u)intptr_t instead of long in stddef.h 2017-07-25 18:56:41 +02:00
Matthias Gatto
23064b1734 check that _Generic match 'signed long int' as 'long' 2017-07-25 18:56:41 +02:00
Matthias Gatto
a4cd2805f9 simplify VT_LONG parsing 2017-07-25 18:56:41 +02:00
Christian Jullien
8258abeb80 Update Cygwin Makefile to work with recent changes about ONE_SOURCE and CONFG_TCCDIR 2017-07-25 17:50:28 +02:00
Matthias Gatto
28b7c9b34e define __SIZE_TYPE__ and __PTRDIFF_TYPE__ as unsigned int and int.
As long is now a qualifier, and because compare_type will notice
that variables are not the same type, we can't use long as int anymore.

So, I've redefine __SIZE_TYPE__ as unsigned int and __PTRDIFF_TYPE__ as int.
2017-07-25 16:25:27 +02:00
Matthias Gatto
b72cddaa6e remove inside_generic hack
define uint64_t and int64_t as 'long' instead of 'long long'
when __LP64__ is define.
2017-07-24 11:52:15 +02:00
grischka
4b3c6e74ab tccgen: nodata_wanted fix, default ONE_SOURCE, etc...
tccgen.c:
  doubles need to be aligned, on ARM.  The section_reserve()
  in init_putv does not do that.
-D ONE_SOURCE: is now the default and not longer needed. Also,
  tcc.h now sets the default native target.  These both make
  compiling tcc simple as "gcc tcc.c -o tcc -ldl" again.
arm-asm.c:
  enable pseudo asm also for inline asm
tests/tests2/Makefile:
  disable bitfield tests except on windows and x86_64
  and don't generate-always
tcc.c:
  fix a loop with -dt on errors
configure:
  print compiler version (as recognized)
tccpp.c:
  actually define symbols for tcc -dt
  clear static variables (needed for -dt or libtcc usage)
96_nodata_wanted.c:
  use __label__ instead of asm
lib/files:
  use native symbols (__i386__ etc.) instead of TCC_TARGET_...
2017-07-23 21:24:11 +02:00
matthias
fdc18d307a mutiples fix for _Generic
* check that _Generic don't match unsigned char * with char *
  this case is usefull as with -funsigned-char, 'char *' are unsigned

* change VT_LONG so it's now a qualifier

  VT_LONG are never use for code generation, but only durring parsing state,
  in _Generic we need to be able to make diference between
  'long' and 'long long'
  So VT_LONG is now use as a type qualifier, it's old behaviour is still
  here, but we can keep trace of what was a long and what wasn't

* add TOK_CLONG and TOK_CULONG

  tcc was directly converting value like '7171L' into TOK_CLLONG or
  TOK_CINT depending of the machine architecture.

  because of that, we was unable to make diference between a long and a
  long long, which doesn't work with _Generic.

  So now 7171L is a TOK_CLONG, and we can handle _Generic properly

* check that _Generic can make diference between long and long long

* uncomment "type match twice" as it should now pass tests on any platforms

* add inside_generic global

  the point of this variable is to use VT_LONG in comparaison only
  when we are evaluating a _Generic.
  problem is with my lastest patchs tcc can now make the diference between
  a 'long long' and a 'long', but in 64 bit stddef.h typedef uint64_t as
  typedef signed long long int int64_t and stdint.h as unsigned long int, so tcc
  break when stdint.h and stddef.h are include together.

  Another solution woud be to modifie include/stddef.h so it define uint64_t as
  unsigned long int when processor is 64 bit, but this could break some
  legacy code, so for now, VT_LONG are use only inside generc.

* check that _Generic parse first argument correctly

* check that _Generic evaluate correctly exresion like "f() / 2"
2017-07-21 19:30:31 +02:00
grischka
0cc24d0e84 tcc -dt -run ... : simpler is better
* -dt now with lowercase t

* test snippets now separated by real preprocessor statements
  which is valid C also for other compilers

    #if defined test_xxx
       < test snippet x >
    #elif defined test_yyy
       < test snippet y >
    #elif ...
    #endif

* simpler implementation, behaves like -run if no 'test_...' macros
  are seen, works with -E too

* for demonstration I combined some of the small tests for errors
  and warnings (56..63,74) in "60_errors_and_warnings.c"

Also:
* libtcc.c:
  put tcc_preprocess() and tcc_assemble() under the setjmp clause
  to let them return to caller after errors.  This is for -dt -E.
* tccgen.c:
  - get rid of save/restore_parse_state(), macro_ptr is saved
    by begin_macro anyway, now line_num too.
  - use expr_eq for parsing _Generic's controlling_type
  - set nocode_wanted with const_wanted. too, This is to keep
    VT_JMP on vtop when parsing preprocessor expressions.
* tccpp.c: tcc -E: suppress trailing whitespace from lines with
  comments (that -E removes) such as
       NO_GOTPLT_ENTRY,\t    /* never generate ... */
2017-07-20 22:21:27 +02:00
Matthias Gatto
ba2b25e4ea fix typo sellector -> selector 2017-07-18 20:28:51 +02:00
matthias
2821644553 fix typo: march -> match 2017-07-18 20:28:51 +02:00
Matthias Gatto
2020a312ca unqualify volatile in _Generic type checking 2017-07-18 20:28:51 +02:00
Michael Matz
3f13e33872 Fix cross compilers
Only native compilers support -run and hence the new -dT.
2017-07-16 21:03:25 +02:00
grischka
7f1ab9b1e1 tccgen: nodata_wanted
The existing variable 'nocode_wanted' is now used to control
output of static data too. So...

(nocode_wanted == 0)
    code and data (normal within functions)
(nocode_wanted < 0)
    means: no code, but data (global or static data)
(nocode_wanted > 0)
    means: no code and no data (code and data suppressed)
(nocode_wanted & 0xC0000000)
    means:  we're in declaration of static data

Also: new option '-dT' to be used with -run
    tcc -dT -run file.c
This will look in file.c for certain comment-boundaries:
    /*-* test-xxx: ...some description */
and then for each test below run it from memory.  This way
various features and error messages can be tested with one
single file.  See 96_nodata_wanted.c for an example.

Also: tccgen.c: one more bitfield fix
2017-07-16 12:10:00 +02:00
grischka
69a137ff88 #pragma comment(option,"-..."), bitfields test, etc...
tccpp.c:
* #pragma comment(option,"-some-option")
  to set commandline option from C code.  May work only
  for some options.
libtcc.c:
* option "-d1..9": sets a 'g_debug' global variable.
  (for development)
tests2/Makefile:
* new make targets: tests2.37 / tests2.37+
  run single test from tests2,  optionally update .expect
* new variable GEN-ALWAYS to always generate certain .expects
* bitfields test
tccgen.c:
* bitfields: fix a bug and improve slightly more
* _Generic: ignore "type match twice"
2017-07-14 19:26:01 +02:00
Michael Matz
04418c7add Fix function types
various cases of function type uses were broken by recent
attribute refactoring, this fixes and adds testcases for them.
2017-07-14 17:42:48 +02:00
Michael Matz
2acb04f7f2 tccasm: Fix local statics referenced from asms
The assembler uses the ->sym_scope member to walk up the symbols
until finding a non-automatic symbol.  Since reordering the
members of Sym the sym_scope member contains a scope even for local
statics.  Formerly the use of asm_label for statics was implicitely
clearing sym_scope, now we have to do that explicitely.

Add a testcase for that, and one I encountered when moving the
clearing of sym_scope too deep into the call chain (into put_extern_sym).
2017-07-10 22:29:28 +02:00
Michael Matz
9bea88d616 Fix statement exprs returning a local label
Like returned local variables also labels local to a statement expression
can be returned, and so their symbols must not be immediately freed
(though they need to be removed from the symbol table).
2017-07-10 22:25:11 +02:00
Michael Matz
2240422da9 enums: Accept GNU extension
See testcase.  Happens e.g. in the linux kernel.
2017-07-10 22:20:34 +02:00
grischka
a9e502cc3b refactor bitfields
Use 2 level strategy to access packed bitfields cleanly:

1) Allow to override the original declaration type with
   an auxilary "access type".  This solves cases such as

    struct {
        ...
        unsigned f1:1;
    };

    by using VT_BYTE to access f1.

2) Allow byte-wise split accesses using two new functions
   load/store_packed_bf. This solves any cases, also ones
   such as

    struct __attribute((packed)) _s {
        unsigned x : 12;
        unsigned char y : 7;
        unsigned z : 28;
        unsigned a: 3;
        unsigned b: 3;
        unsigned c: 3;
    };

    where for field 'z':
    - VT_INT access from offset 2 would be unaligned
    - VT_LLONG from offset 0 would go past the total
      struct size (7)

    and for field 'a' because it is in two bytes and
    aligned access with VT_SHORT/INT is not possible.

Also, static bitfield initializers are stored byte-wise always.
Also, cleanup the struct_layout function a bit.
2017-07-09 12:38:59 +02:00
grischka
f87afa72e0 refactor enums
Eliminate VT_ENUM as a basic type.  Instead use the integral
types VT_InT/VT_LLONG with an additional flag to indicate
that it is an enum.
2017-07-09 12:38:25 +02:00
grischka
9ba76ac834 refactor sym & attributes
tcc.h:
* cleanup struct 'Sym'
* include some 'Attributes' into 'Sym'
* in turn get rid of VT_IM/EXPORT, VT_WEAK
* re-number VT_XXX flags
* replace some 'long' function args by 'int'

tccgen.c:
* refactor parse_btype()
2017-07-09 12:34:11 +02:00
grischka
9f79b62ec4 unsorted adjustments
- configure
  * use aarch64 instead of arm64

- Makefile
  * rename the custom include file to "config-extra.mak"
  * Also avoid "rm -r /*" if $(tccdir) is empty

- pp/Makefile
  * fix .expect generation with gcc

- tcc.h
  * cleanup #defines for _MSC_VER

- tccgen.c:
  * fix const-propagation for &,|
  * fix anonymous named struct (ms-extension) and enable
    -fms-extension by default

- i386-gen.c
  * clear VT_DEFSIGN

- x86_64-gen.c/win64:
  * fix passing structs in registers
  * fix alloca (need to keep "func_scratch" below each alloca area on stack)
    (This allows to compile a working gnu-make on win64)

- tccpp.c
  * alternative approach to 37999a4fbf
    This is to avoid some slowdown with ## token pasting.
  * get_tok_str() : return <eof> for TOK_EOF
  * -funsigned-char: apply to "string" literals as well

- tccpe/tools.c: -impdef: support both 32 and 64 bit dlls anyway
2017-07-09 12:07:40 +02:00
grischka
6c468c10f7 tccpp: allow "#define X defined Y ..."
That means: we do not macro-expand the argument of 'defined'

Also: store the last token position into the TokenString
structure in order to get rid of the tok_last function.
2017-07-09 11:46:14 +02:00
Michael Matz
824dcebe59 tccpp: Implement __COUNTER__
This requires one more change in how macro arguments are expanded:
the standard requires that macro args are expanded before substituting
into the replacement list.  This implies expanding them only once
even when they occur multiple times in the list.  TCC expanded
them repeatedly in that case.  Without __COUNTER__ that's harmless.

So, simply always expand arguments (when used without # and ##) once
and store the resulting tokens.
2017-07-09 05:30:47 +02:00
Michael Matz
1f3d3957c4 tccpp: Cleanup
With last change the can_read_stream flag is unneeded, so tidy this
a bit.
2017-07-09 04:53:24 +02:00
Michael Matz
d8fdd380f3 tccpp: Fix corner case
See added testcase 19.c from a bug report.  The problem is reading outside
the arguments buffers, even though we aren't allowed to.  The single
can_read_stream variable is not enough, sometimes we need to be able
to pop into outer contexts but not into arbitrarily outside contexts.

The trick is to terminate argument tokens with a EOF (and not just with
0 that makes us pop contexts), and deal with that in the few places
we have to,

This enables some cleanups of the can_read_stream variable use.
2017-07-09 04:38:56 +02:00
Matthias Gatto
16d3dbf2d0 add _Generic test 2017-07-05 17:59:42 +02:00
Matthias Gatto
157bad52cd add C11's _Generic
Simple implementation, I'm not even sure to respect C standart here,
but it should work with most use case.

This add an case in unary(), and generate TokString depending of _Generic
controlling exression, use begin_macro to "push"
the generated TokString, then call unary() again before exiting the switch
so the just add token are reevaluate again.
2017-07-05 10:57:50 +02:00
Michael Matz
9ed8b54f6c Revert "String literals are always const"
This reverts commit d4fe9aba3f.
I was confused by the fact that string literals aren't writable.
Nevertheless the type isn't const.  As extension in GCC it's const
with -Wwrite-string, which is exactly what we had before.

GCC also wonders in a comment if it's really a good idea to change
expression types based on warning flags (IMHO it's not), but let's
be compatible.  So restore the state from before.
2017-07-04 16:37:49 +02:00
Michael Matz
580ad5f24c Extend skip_or_save_block
Make it stop also before outer level closing parens.  This way
we can now also skip/save the expression inside "foobar(42 + 41)".
2017-07-03 19:15:16 +02:00
Michael Matz
27ca303874 Improve skip_or_save_block
Stop at level 0 only for matching outer '}' (which is added).
Otherwise stop only at stop tokens (which aren't added).
2017-07-03 18:13:15 +02:00
Michael Matz
d4fe9aba3f String literals are always const
Don't make the standard mandated types of string literals
depends on warning options.  Instead make them always const,
but limit the emission of the warning by that option.
2017-07-03 18:02:57 +02:00
Christian Jullien
b68df809eb Align 'implicit-function-declaration' option comment with other comments (cosmetic change) 2017-06-10 06:45:51 +02:00
Christian Jullien
6d559d651f Add -O2 when compiling tcc on Windows. Not sure this flag is really used by tcc. 2017-06-10 06:35:11 +02:00
Emil
3e028af453 When creating a staticaly linked ELF program should not include
any dyn symbols. The if( !s1->static_link ) prevents tcc from
crashing when buiding a program linked to dietlibc.

The section header should not contain the number of local symbols when
the sh_size is null. This makes the header compliant and IDA will not
issue any warnings when an executable is disassembled.
2017-06-09 19:44:29 +01:00
U-NELSON\jullien
3e4b7693bf force i386-win32-tcc.exe to be a 32bit binary. Run tests in both 32/64 bits on Windows. 2017-06-05 08:18:11 +02:00
U-NELSON\jullien
2a348896dd Add more common tests to be run from win32/Makefile 2017-06-04 09:27:48 +02:00
Christian Jullien
0cc4e570bc Windows test Makefile target also test pp tests. 2017-05-28 07:12:57 +02:00
Michael Matz
31e5ad789a Limit access end-of-struct warning a bit
Only warn if the struct has a non-zero size.  You can't create objects
of zero-sized structs, but they can be used inside sizeof (e.g.
"sizeof (struct {int :0;})".  The warning would always trigger for these,
but as no objects can be created no accesses can ever happen.
2017-05-27 22:44:53 +02:00
Michael Matz
7cd1ae7710 x86-64: Fix psABI stdarg prologue
If there were more than 6 integer arguments before the ellipsis, or
there were used more than 8 slots used until the ellipsis (e.g. by
a large intermediate struct) we generated wrong code.  See testcase.
2017-05-27 22:42:18 +02:00
Michael Matz
53c5fc2246 x86-64: Rewrite linux parameter passing
This fixes two ABI testcases involving large arguments when there
are still registers available for later args.
2017-05-27 21:23:13 +02:00
Aron BARATH
307b7b183d the R_X86_64_GOTOFF64 relocation was missing 2017-05-16 07:03:26 +02:00
grischka
28435ec58c configure: --config-musl/-uClibc switch & misc cleanups
- configure:
  - add --config-uClibc,-musl switch and suggest to use
    it if uClibc/musl is detected
  - make warning options magic clang compatible
  - simplify (use $confvars instead of individual options)
- Revert "Remove some unused-parameter lint"
  7443db0d5f
  rather use -Wno-unused-parameter (or just not -Wextra)
- #ifdef functions that are unused on some targets
- tccgen.c: use PTR_SIZE==8 instead of (X86_64 || ARM64)
- tccpe.c: fix some warnings
- integrate dummy arm-asm better
2017-05-13 08:59:06 +02:00
Aron BARATH
3a9d6b3655 added 64-bit relocation types that required to linking against 64-bit (large model) libraries 2017-05-12 09:31:09 +02:00
grischka
1ed20a01c9 bitfields: promote to signed int
For integer promotion with for example arithmetics or
expr_cond (x ? y : z), integral types need to be promoted
to signed if they fit.

According to latest standards, this also applies to bit-field
types taking into account their specific width.

In tcc, VT_BITFIELD set means width < original type width
Field-widths between 33 and 63 are promoted to signed long long
accordingly.

    struct { unsigned long long ullb:35; } s = { 1 };
    #define X (s.ullb - 2)

    int main (void)
    {
        long long Y = X;
        printf("%d %016llx %016llx\n", X < 0, -X, -Y);
        return 0;
    }

Results:
    GCC 4.7 : 0 0000000000000001 FFFFFFF800000001
    MSVC    : 1 0000000000000001 0000000000000001
    TCC     : 1 0000000000000001 0000000000000001

Also, gcc would promote long long bitfields of size < 32
to int as well.  Example:

    struct { unsigned long long x:20; } t = { 123 };
    /* with gcc: */ printf("%d %d\n", t.x, 456);
    /* with tcc: */ printf("%lld %d\n", t.x, 456);
2017-05-09 18:36:24 +02:00
grischka
d242706f3b bitfields: one more hack and a "-Wgcc-compat" switch
bit_pos + bit_size > type_size * 8

must NEVER happen because the code generator can read/write
only the basic integral types.

Warn if tcc has to break GCC compatibility for that reason
and if -Wgcc-compat is given.

Example:
    struct __attribute__((packed)) _s
    {
        unsigned int x  : 12;
        unsigned char y :  7;
        unsigned int z  : 28;
    };

Expected (GCC) layout (sizeof struct = 6)
.xxxxxxxx.xxxxyyyy.yyyzzzzz.zzzzzzzz.zzzzzzzz.zzzzzzz0.

But we cannot read/write 'char y'from 2 bytes in memory.
So we have to adjust:
.xxxxxxxx.xxxx0000.yyyyyyyz.zzzzzzzz.zzzzzzzz.zzzzzzzz.zzz00000

Now 'int z' cannot be accessed from 5 bytes.  So we arrive
at this (sizeof struct = 7):
.xxxxxxxx.xxxx0000.yyyyyyy0.zzzzzzzz.zzzzzzzz.zzzzzzzz.zzzz0000

Otherwise the bitfield load/store generator needs to be
changed to allow byte-wise accesses.

Also we may touch memory past the struct in some cases
currently.  The patch adds a warning for that too.

   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	81 ec 04 00 00 00    	sub    $0x4,%esp
   9:	90                   	nop

    struct __attribute__((packed)) { unsigned x : 5; } b = {0} ;

   a:	8b 45 ff             	mov    -0x1(%ebp),%eax
   d:	83 e0 e0             	and    $0xffffffe0,%eax
  10:	89 45 ff             	mov    %eax,-0x1(%ebp)

This touches -0x1 ... +0x3(%ebp), hence 3 bytes beyond
stack space.  Since the data is not changed, nothing
else happens here.
2017-05-09 18:10:02 +02:00
Larry Doolittle
3f5fd305af Touch up previous "s"[i<2] patch
The real equivalence is between the original "s" + (i<2)
and &"s"[i<2].
2017-05-09 07:08:43 -07:00
Larry Doolittle
3c0a73822d Give clang one less thing to complain about
"s"[i<2] and "s" + (i<2) are literally identical, but the latter triggers
a warning from clang because it looks so much like a noob is trying to
concatenate an integer and a string.  The former is arguably more clear.
2017-05-08 21:56:38 -07:00
Michael Matz
dfb75d9b6c Remove some unused arguments
these ones are really superfluous.
2017-05-08 20:26:59 +02:00
Michael Matz
377e8e5e68 bitfields: fix long bitfields
now the testcase works on i386-linux as well.
2017-05-08 19:58:31 +02:00
Marc Vertes
1094891e67 Improve musl and uclibc detection
Do not enable musl or uclibc native support if a GNU linker is
already present. This avoids interference for example on a
Debian platform with musl-dev installed. More work is required
to select musl libc in that case, with additional configure flags.
2017-05-08 16:14:35 +00:00
Larry Doolittle
70fca7f799 Fix spelling in help message
"seach" becomes "search" in help2 when not TCC_TARGET_PE
2017-05-08 08:44:52 -07:00
Larry Doolittle
7443db0d5f Remove some unused-parameter lint
Mark TCCState parameter as unused in tcc_undefine_symbol(), tcc_add_symbol(),
tcc_print_stats(), asm_get_local_label_name(), use_section1(), tccpp_delete(),
tcc_tool_ar(), tcc_tool_impdef(), and tcc_tool_cross().
Also mark it unused in tcc_add_bcheck() unless CONFIG_TCC_BCHECK.
Remove it entirely in ld_next().
2017-05-08 08:30:43 -07:00
Christian Jullien
56df27502c C string litteral is const, fix return type of default_elfinterp. Remove #ifndef TCC_IS_NATIVE in arm-gen.c as suggested by grischka. 2017-05-08 09:18:27 +02:00
Larry Doolittle
19d8b8a173 Spelling fixes in C comments only 2017-05-07 21:38:09 -07:00
Larry Doolittle
1b9935cf36 Add missing const and add warning flags 2017-05-07 21:28:05 -07:00
Michael Matz
524f6dff17 Fix a warning
"missing intitializer for field op_type" with gcc -Wextra.  It's
zero-initialized anyway, and not that much a hassle to explicitely
initialize either, so let's be nice and make it not warn.
2017-05-08 05:29:54 +02:00
grischka
44abffe33a more minor fixes
* tccgen: re-allow long double constants for x87 cross
  sizeof (long double) may be 12 or 16 depending on host platform
  (i386/x86_64 on unix/windows).
  Except that it's 8 if the host is on windows and not gcc
  was used to compile tcc.

* win64: fix builtin_va_start after VT_REF removal
  See also a8b83ce43a

* tcctest.c: remove outdated limitation for ll-bitfield test
  It always worked, there is no reason why it should not work
  in future.

* libtcc1.c: exclude long double conversion on ARM

* Makefile: remove CFLAGS from link recipes

* lib/Makefile: use target DEFINES as passed from main Makefile

* lib/armflush.c lib/va_list.c: factor out from libtcc1.c

* arm-gen.c: disable "depreciated" warnings for now
2017-05-07 12:41:29 +02:00
Michael Matz
94ac9f2b49 Accept extern initialized file-scope variables
'extern int i = 42;' at file scope (but not in function scope!) is
allowed and is a proper definition, even though questionable style;
some compilers warn about this.
2017-05-07 08:10:06 +02:00
Michael Matz
5732a1882e elf: Fix last commit
Forgot to mark tccelf.c as to be committed in last commit :-/
2017-05-07 04:52:21 +02:00
Michael Matz
680e84fe42 elf: Support STB_LOCAL dynamic symbols
local symbols can be resolved statically, they don't have to be
done dynamically, so this is a slight speedup at load time for
produced executables and shared libs.  The musl libc also rejects
any STB_LOCAL symbols for dynamic symbol resolution, so there it
also fixes use of shared libs created by tcc.
2017-05-07 04:41:40 +02:00
Michael Matz
600018ce47 elf: Ignore SHF_COMPRESSED sections
some newer systems have debug sections compressed by default, which
includes those in the crt[1in].o startup files.  These can't simply
be concatenated like all others (which leads to invalid section contents
ultimately making gdb fail) but need special handling.

Instead of that special handling (decompressing, which in turn requires
linking against zlib) let's just ignore such sections, even though that
means to also ignore all other debug sections from that particular input
file.  Our own generated files of course don't have the problem.
2017-05-06 07:30:44 +02:00
Michael Matz
ff998900b1 struct-init: Fix zero initialization with multi-level designators
See the added testcase.  When one used designators like .a.x to initialize
sub-members of members, and didn't then initialize all of them the
required zero-initialization of the other sub-members wasn't done.
The fix also enables tiny code cleanups.
2017-05-06 05:28:13 +02:00
Michael Matz
0757234560 Fix unsigned enum bit-fields
See testcase.  If an enum has only positive values, fits N bits,
and is placed in a N-bit bit-field that bit-fields must be treated
as unsigned, not signed.
2017-05-05 23:16:43 +02:00
Michael Matz
a7a3627ab2 Fix segfault with invalid function def
This invalid function definition:
  int f()[] {}
was tried to be handled but there was no testcase if it actually worked.
This fixes it and adds a TCC only testcase.
2017-05-05 22:01:02 +02:00
Michael Matz
d4878985e8 Rebuild cross compilers when sources change
ONE_SOURCE=yes cross-compilers currently only depend on tcc.c, which
itself has no further deps.  So e.g. changing tccgen.c or tcctok.h
don't automatically rebuild cross compilers.  Let's go over
the intermediate $(X)tcc.o file which automatically depends on
LIBTCC_INC, which are all relevant source files.
2017-05-02 03:14:05 +02:00
Michael Matz
149678e888 Tidy decl_designator
Removing the need for the notfirst local variable, and tidy loop structure
and error messaging a bit.
2017-05-02 03:14:05 +02:00
Michael Matz
9839b60177 Remove label_or_decl
The only use of this function can be rewritten in terms of
is_label (if one other use of that one are a bit amended).
2017-05-02 03:14:05 +02:00
Michael Matz
c7dbc900c8 Cleanups (float consts, sections, symbols)
introduce common_section (SHN_COMMON), factorize some handling
in decl_initializer_alloc, add section_add and use it to factorize
some code that allocates stuff in sections (at the same time also fixing
harmless bugs re section alignment), use init_putv to emit float consts
into .data from gv() (fixing an XXX).
2017-05-02 03:13:55 +02:00
Michael Matz
25522e4799 Merge func_decl_list into decl0
Removes some code duplication and also implements one feature:
checking for duplicate decls for old style parameters.
2017-05-02 03:07:37 +02:00
Michael Matz
7aef0522b0 Tidy decl_designator
The fixme therein is long solved.
2017-05-02 03:07:37 +02:00
Michael Matz
8ca98e23c4 Tidy unary() a bit
factor code a bit for transforming tokens into SValues.  This revealed
a bug in TOK_GET (see testcase), which happened to be harmless before.
So fix that as well.
2017-05-02 03:07:37 +02:00
Michael Matz
21b12ea10d Factor some code
Three places that skip (and store) tokens in some fashion can
be factored a bit.
2017-05-02 03:07:37 +02:00
Michael Matz
328b06a3fc Extend type_to_str
to also print storage-class specifiers.
2017-05-02 03:07:36 +02:00
Michael Matz
182367e232 Reorganize type parsing
Various corner cases for declarator parsing were incorrect.  This
reorganizes and fixes it, and somewhat simplifies it as well.
2017-05-02 03:07:36 +02:00
Michael Matz
5891fbc0c8 Tidy typename parsing a bit 2017-05-02 03:07:36 +02:00
Michael Matz
51314932e3 Tidy arg parsing for builtins
Saves some lines of code.
2017-05-02 03:07:36 +02:00
Michael Matz
10551d6961 Clarify that the CIL target code is dead
This backend doesn't work anymore since a long time.
Don't remove it yet, it might be an inspiration.
2017-05-02 03:07:36 +02:00
Michael Matz
a8b83ce43a Remove VT_REF
The canonical way to describe a local variable that actually holds
the address of an lvalue is VT_LLOCAL.  Remove the last user of VT_REF,
and handling of it, thereby freeing a flag for SValue.r.
2017-05-02 03:07:36 +02:00
Michael Matz
8b9697ca6b Fix bogus check for VT_LLOCAL types
VT_LLOCAL is a flag on .r, not on type.t.  Fixing this requires
minor surgery for compound literals which accidentally happened
to be subsumed by the bogus test.
2017-05-02 03:07:36 +02:00
Michael Matz
24420bb5c0 elf: Tidy section headers
Don't emit useless section headers and also sort them in allocated
order.  Doesn't change behaviour except makes the resulting files
a tiny bit smaller (though at the expense of some very tiny compile
time and code size increase of tcc itself; not 100% it's worth it).
2017-05-02 03:07:36 +02:00
Michael Matz
3c39cb5cd8 fix __builtin_expect
the second argument can be an arbitrary expression (including
side-effects), not just a constant.  This removes the last user
of expr_lor_const and hence also that function (and expr_land_const).
Also the argument to __builtin_constant_p can be only a non-comma
expression (like all functions arguments).
2017-05-02 03:07:36 +02:00
Michael Matz
8d9dd3c008 Fix more bitfield corner cases
Our code generation assumes that it can load/store with the
bit-fields base type, so bit_pos/bit_size must be in range for this.
We could change the fields type or adjust offset/bit_pos; we do the
latter.
2017-05-01 06:18:48 +02:00
Michael Matz
4ce73354fc Fix last change
Skipping anonymous bit-fields is correct, but not other
anonymous ones like unions or structs.
2017-05-01 06:04:19 +02:00
Michael Matz
f775d68725 Remove a bit-field TODO
Checked the lcc testsuite for bitfield stuff (in cq.c and fields.c),
fixed one more error in initializing unnamed members (which have
to be skipped), removed the TODO.
2017-04-29 22:09:10 +02:00
Michael Matz
28084420fe Fix char bitfields corner case
See testcase.
2017-04-29 21:25:31 +02:00
Thomas Stalder
76e16465bf arm: Fix build_got_entries 2017-04-27 14:16:49 +02:00
Christian Jullien
f12851e388 Add -static to be in sync with Windows bat. 2017-04-27 07:01:46 +02:00
grischka
a35752d233 configure: fix permissions
There must be something with git on windows that it
messes up x permissions sometimes.
2017-04-26 00:01:23 +02:00
Larry Doolittle
37999a4fbf Simple-minded fix for bug #50847
bug #50847: #line directive corrupts #include search path
Keep a second copy of the filename, that isn't changed by the #line directive,
and use that on the initial search path for #include files.
2017-04-25 12:32:41 -07:00
grischka
7acf9aa862 final adjustments for release
- configure/Makefiles: minor adjustments

- build-tcc.bat: add -static to gcc options
  (avoids libgcc_s*.dll dependency with some mingw versions)

- tccpe.c/tcctools.c: eliminate MAX_PATH
  (not available for cross compilers)

- tccasm.c: use uint64_t/strtoull in unary()
  (unsigned long sometimes is only uint32_t, as always on windows)

- tccgen.c: Revert (f077d16c) "tccgen: gen_cast: cast FLOAT to DOUBLE"
  Was a rather experimental, tentative commit, not really necessary
  and somewhat ugly too.

- cleanup recent osx support:
  - Makefile/libtcc.c: cleanup copy&paste code
  - tccpp.c: restore deleted function
2017-04-25 21:01:54 +02:00
Andrei Warkentin
fb4f57666c tcc: report Darwin when building for Mach-O binaries.
Somewhat revert c4c3f50, but key off the config, not
host system.

Signed-off-by: Andrei Warkentin <andrey.warkentin@gmail.com>
2017-04-25 13:57:33 +03:00
Andrei Warkentin
63b2f907bd tcc: fixup clang warnings
The O(xxx) stuff in i386-asm.c had me scratching my head. Extracting
the macro and trying it out in a separate program doesn't give
me any warnings, so I'm confused about what could be going on there.
Any cast will make things happy. I used a uint64_t to catch actual
cases of overflow, which will still cause a -Wconstant-conversion
warning.

Signed-off-by: Andrei Warkentin <andrey.warkentin@gmail.com>
2017-04-25 13:55:18 +03:00
Andrei Warkentin
91cd148a05 tcc: early OSX native support
- build scripts
- working '-run' mode, e.g.:

./tcc -B. -I./include -I. -I.. -D_ANSI_SOURCE -run examples/ex1.c

Note: we don't bother parsing Mach-O/Fat images yet. We blindly
dlopen the image.

Signed-off-by: Andrei Warkentin <andrey.warkentin@gmail.com>
2017-04-25 13:55:18 +03:00
Marc Vertes
0ac29b53dc Add support of musl-libc
The port is functional. Bound checking is not supported yet.
2017-04-20 22:01:50 +02:00
Michael Matz
328b826e8a tccpp: Fix corner case of fnlike macro invocation
Arg substitution leaves placeholder marker in the stream for
empty arguments.  Those need to be skipped when searching for
a fnlike macro invocation in the replacement list itself.  See
testcase.
2017-04-15 19:34:55 +02:00
grischka
536ed76d5a tccgen/win32: let __declspec(dllimport) imply extern
Also, retain storage qualifiers in type_decl, in particular
also for function pointers.  This allows to get rid of this
very early hack in decl()
    type.t |= (btype.t & VT_STATIC); /* Retain "static". */
which was to fix the case of
    int main() { static int (*foo)(); ...

Also:
- missing __declspec(dllimport) is an error now
- except if the symbol is "_imp__symbol"
- demonstrate export/import of data in the dll example (while
  'extern' isn't strictly required with dllimport anymore)
- new function 'patch_storage()' replaces 'weaken_symbol()'
  and 'apply_visibility()'
- new function 'update_storage()' applies storage attributes
  to Elf symbols.
- put_extern_sym/2 accepts new pseudo section SECTION_COMMON
- add -Wl,-export-all-symbols as alias for -rdynamic
- add -Wl,-subsystem=windows for mingw compatibility
- redefinition of 'sym' error for initialized global data
2017-04-04 08:34:52 +02:00
Christian Jullien
c4c3f5009e Even on Darwin, tcc should display Linux 2017-02-26 16:28:52 +01:00
Avi Halachmi (:avih)
2da36731da win: tests Makefile: fix global path
Commit bb93064 changed the path seperator from ':' to ';', which was
likely accidental. While path seperator on Windows is generally ';', the
Makefile clearly expects a posix-y shell, and in such environments the
separator is ':'.

This fixes the test run in MSYS2 and MSYS(1) environments, which got
broken on bb93064 .
2017-02-26 15:41:26 +02:00
Christian Jullien
206829415a Linux was incorrectly identified in banner when compiled on macOS Darwin 2017-02-26 08:02:53 +01:00
grischka
bb93064d78 makefile: unify cross with native builds
supports building cross compilers on the fly without need
for configure --enable-cross

   $ make cross          # all compilers
   $ make cross-TARGET   # only TARGET-compiler & its libtcc1.a

with TARGET one from
   i386 x86_64 i386-win32 x86_64-win32 arm arm64 arm-wince c67

Type 'make help' for more information
2017-02-25 12:51:04 +01:00
Christian Jullien
669f61117d Cygwin Makefile was to aggresive to remove entire lib/ 2017-02-24 22:51:10 +01:00
Christian Jullien
2e0a8f9b37 Update Cygwin Makefile for new libtcc1-xx.a layout 2017-02-24 22:39:06 +01:00
grischka
569255e6c4 cross-compilers: allow individual configuration
since configure supports only native configuration
a file 'cross-tcc.mak' needs to be created manually.
It is included in the Makefile if present.

# ----------------------------------------------------
# Example config-cross.mak:
#
# windows -> i386-linux cross-compiler
# (it expects the linux files in <prefix>/i386-linux)

ROOT-i386 = {B}/i386-linux
CRT-i386 = $(ROOT-i386)/usr/lib
LIB-i386 = $(ROOT-i386)/lib:$(ROOT-i386)/usr/lib
INC-i386 = {B}/lib/include:$(ROOT-i386)/usr/include
DEF-i386 += -D__linux__

# ----------------------------------------------------

Also:
- use libtcc1-<target>.a instead of directories
- add dummy arm assembler
- remove include dependencies from armeabi.c/lib-arm64.c
- tccelf/ld_add_file: add SYSROOT (when defined) to absolute
  filenames coming from ld-scripts
2017-02-23 08:41:57 +01:00
Christian Jullien
576bee9a37 Add note about native Windows bootstrap using Cygwin. 2017-02-23 06:45:26 +01:00
Michael Matz
3e4c296eba x86-64-asm: Fix mov im64,rax encoding
the avoidance of mov im32->reg64 wasn't working when reg64 was rax.
While fixing this also fix instructions which had the REX prefix
hardcoded in opcode and so didn't support extended registers which
would have added another REX prefix.
2017-02-23 00:16:25 +01:00
Michael Matz
e209b7dac4 Update ChangeLog
with more things I remember having done :)
2017-02-20 20:24:30 +01:00
grischka
5f33d313c8 tcc: re-enable correct option -r support
Forgot about it.  It allows to compile several
sources (and other .o's) to one single .o file;

    tcc -r -o all.o f1.c f2.c f3.S o4.o ...

Also:
- option -fold-struct-init-code removed, no effect anymore
- (tcc_)set_environment() moved to tcc.c
- win32/lib/(win)crt1 minor fix & add dependency
- debug line output for asm (tcc -c -g xxx.S) enabled
- configure/Makefiles: x86-64 -> x86_64 changes
- README: cleanup
2017-02-20 18:58:08 +01:00
Christian Jullien
399237850d Update cygwin Makefile after recent Windows source changes 2017-02-18 14:53:31 +01:00
grischka
5286529632 tcc -hh: show more options 2017-02-18 09:55:46 +01:00
grischka
2d3b9559bf tcctools.c: integrate tiny_libmaker/_impdef
usage:
    tcc -ar [rcsv] lib files...
    tcc -impdef lib.dll [-v] [-o lib.def]

also:
- support more files with -c: tcc -c f1.c f2.c ...
- fix a bug which caused tcc f1.c f2.S to produce no asm
- allow tcc -ar @listfile too
- change prototype: _void_ tcc_set_options(...)
- apply -Wl,-whole-archive when a librariy is given
  as libxxx.a also (not just for -lxxx)
2017-02-18 09:55:34 +01:00
Steffen Nurpmeso
f34b1feaca -Wl, --enable-new-dtags for DT_RUNPATH instead of DT_RPATH
Today by accident i had to deal with linker problems of some
software and found an issue that mentioned DT_RUNPATH, which
mentioned that DT_RPATH is legacy and searched for
$LD_LIBRARY_PATH, whereas the newer DT_RUNPATH is searched
thereafter.  Completely unencrypted!  Well.  For what's it worth,
i for one am astonished because of course i want to override
$LD_LIBRARY_PATH, but it surely has its merites, smart people came
to the conclusion, did they.

The attached diff below seems to be sufficient to support
DT_RUNPATH instead of DT_RPATH with tcc(1).  But i have no insight
in what --enable-new-dtags is supposed to change in addition, so
i wonder.

Ciao!

--steffen

 libtcc.c     | 2 ++
 tcc-doc.texi | 4 ++++
 tcc.h        | 1 +
 tccelf.c     | 3 ++-
 4 files changed, 9 insertions(+), 1 deletion(-)
2017-02-18 09:54:41 +01:00
grischka
096125d963 win32: adjust new unicode support
- lib/Makefile: add (win)crt1_w.o

- crt1.c/_runtmain: return to tcc & only use for UNICODE
  (because it might be not 100% reliable with for example
  wildcards (tcc *.c -run ...)

- tccrun.c/tccpe.c: load -run startup_code only if called
  from tcc_run(). Otherwise main may not be defined.  See
  libtcc_test.c

- tests2/Makefile: pass extra options in FLAGS to allow
  overriding TCC

Also:
- tccpe.c: support weak attribute.  (I first tried to solve
  the problem above by using it but then didn't)
2017-02-18 09:51:23 +01:00
Christian Jullien
39b2afeb7c Temporary remove 76_dollards_in_identifiers when run on Windows as this test failes. To be checked why. 2017-02-18 08:12:00 +01:00
Christian Jullien
9bd04fa000 Makefile for Windows native tcc handles recent UNICODE support 2017-02-18 08:00:58 +01:00
YX Hao
86e3cd0c5a Add support for Unicode entries 'wmain' and 'wWinMain' on Windows
'-run' suported. argvs are converted.
But don't use compliled Unicode CLI exe-file to get inputs interactively in other codepage!
Please add other compliling supports than 'build-tcc.bat' (Who is good at them).
2017-02-17 21:09:26 +08:00
Christian Jullien
f33801e25e Add entry to run tests2 tests 2017-02-17 08:05:38 +01:00
Christian Jullien
d61985b37a tiny_impldef.exe was not built by Makefile 2017-02-16 07:01:44 +01:00
Christian Jullien
7b99c3ac2c Fix wrong name for 85 test. 2017-02-15 09:00:38 +01:00
Vlad Vissoultchev
67fe371f84 win32: build-tcc.bat: figure out correct bitness of cl.exe 2017-02-14 11:45:35 +02:00
Christian Jullien
5550e4336f Improve cygwin Makefile that now support TARGET=32/64 to force final version for 32/64 platform 2017-02-14 05:51:45 +01:00
grischka
43d9a7de9b updates & cleanups (tcc-doc/Changelog/TODO ...)
- tcc-doc.texi: commandline option info update
- Changelog/TODO: update
- tests/tcctest.py: removed
- tests/Makefile: weaktest fixed
- tests/tests2: some files renamed and/or converted to unix LF
- configure/Makefile: --enable-static option (no dll on win32)
- win32/build-tcc.bat: msvc support
- win32/tcc-win32.txt: build info update
- win32/vs2015/: VS solution removed
- win32/include/tcc/tcc_libm.h: #include statement fixed
- tcc.c: -include <file> option help info
- .gitignore: cleanup
2017-02-13 19:03:29 +01:00
grischka
13056da039 mems & leaks
- define_start: set above preprocess_start because now
  preprocess_start is defining macros.

- free "cmd_include_files"
- free defines always (after error-longjmps)
- close all files (after error-longjmps)
- tccpe.c: free imports always
- libtcc.c: call tcc_memstats only after all states have
  been deleted.
2017-02-13 18:23:55 +01:00
grischka
a4a20360e9 fixes & cleanups
- tccgen.c/tcc.h: allow function declaration after use:
      int f() { return g(); }
      int g() { return 1; }
  may be a warning but not an error
  see also 76cb1144ef

- tccgen.c: redundant code related to inline functions removed
  (functions used anywhere have sym->c set automatically)

- tccgen.c: make 32bit llop non-equal test portable
  (probably not on C67)

- dynarray_add: change prototype to possibly avoid aliasing
  problems or at least warnings

- lib/alloca*.S: ".section .note.GNU-stack,"",%progbits" removed
  (has no effect)

- tccpe: set SizeOfCode field (for correct upx decompression)

- libtcc.c: fixed alternative -run invocation
      tcc "-run -lxxx ..." file.c
  (meant to load the library after file).
  Also supported now:
      tcc files ... options ... -run @ arguments ...
2017-02-13 18:23:43 +01:00
Christian Jullien
9817204d8a Detect native version from default gcc target. 2017-02-12 17:06:27 +01:00
grischka
ec6a997f80 tccgen: yet another nocode_wanted fix
Some code in gen_opl was depending on a gvtst label
which in nocode_wanted mode is not set.

This was causing vstack leaks and crashes with for example

  long long ll;
  if (0)
      return ll - 10 < 0;
2017-02-12 13:21:20 +01:00
Christian Jullien
417a1ed384 Add Makefile to build native tcc 32/64 on Windows using cygwin 2017-02-12 12:14:27 +01:00
Michael Matz
983520d721 arm64: Fix 42_function_test
Like in 77d7ea04a some relocs need to be handled as possibly
needing a PLT/GOT slot in TCC until TCC can transfer dynamic relocs
to executables.
2017-02-11 10:16:55 +01:00
Michael Matz
15f990bf71 Fix testsuite invocations
The return code of $(FILTER) clobbers the return code of
TCC itself.  So just prepend messages to the generated output file
and ignore return codes.
2017-02-11 14:27:21 +01:00
grischka
ee5425fe95 libtcc: support multiple -Wl,-rpath=...'s 2017-02-11 09:54:01 +01:00
grischka
362cafb471 arm: libtcc1.a needs gcc with -fPIC 2017-02-11 09:30:20 +01:00
Vlad Vissoultchev
910a6bc859 Add pre-build step in VS2015 projects to generate config.h from VERSION 2017-02-09 13:31:12 +02:00
grischka
5efa75d9b8 update VERSION to 0.9.27
Also:
- in tests: generate .expect files only if not yet present,
  because
  1) some files were adjusted manually
  2) switching git branche might change timestamps and
     cause unwanted update
2017-02-08 19:56:15 +01:00
grischka
aa0a45be05 win32: build-tcc.bat: add some options
In particular:

-c <compiler> : Allow using tcc to compile itself
-i <dir>      : Create installation in dir

Summary:

usage: build-tcc.bat [ options ... ]
options:
  -c prog              use prog (gcc or tcc) to compile tcc
  -c "prog options"    use prog with options to compile tcc
  -t 32/64             force 32/64 bit default target
  -v "version"         set tcc version
  -i dir               install tcc into dir
  -d                   create tcc-doc.html too (needs makeinfo)
2017-02-08 19:53:49 +01:00
grischka
e596b871a9 win32: include/winapi: remove more files
Also: use _assert, older msvcrt does not have _wassert
2017-02-08 19:53:02 +01:00
grischka
90316c7c26 tcc: don't use pstrcpy, fix win32 spanwn quoting
- we're now exporting tcc_prefixed symbols from libtcc only

- On windows, the msvcrt startup code would remove backslashes
  from commandline arguments such as
      -DFOO=\"foo\"
  which would appear in argv as
      -DFOO="foo"
  Therefor before passing these to spawnvp, we need to restore
  the backslashes.
2017-02-08 19:49:28 +01:00
grischka
68666eee2a tccgen: factor out gfunc_return
Also:
- on windows i386 and x86-64, structures of size <= 8 are
  NOT returned in registers if size is not one of 1,2,4,8.
- cleanup: put all tv-push/pop/swap/rot into one place
2017-02-08 19:45:31 +01:00
grischka
f077d16c20 tccgen: gen_cast: cast FLOAT to DOUBLE
... to avoid precision loss when casting to int,
also when saving FLOATs to stack
2017-02-05 14:30:20 +01:00
grischka
3b84e61ead Revert "partial revert of the commit 4ad186c5ef61"
There seems nothing wrong.  With

    int t1 = 176401255;
    float f = 0.25;
    int t2 = t1 * f; // 176401255 * 0.25 = 44100313.75

according to the arithmetic conversion rules, the number
176401255 needs to be converted to float, and the compiler
can choose either the nearest higher or nearest lower
representable number "in an implementation-defined manner".

Which may be 176401248 or 176401264.  So as result both
44100312 and 44100313 are correct.

This reverts commit 664c19ad5e.
2017-02-05 14:30:19 +01:00
grischka
85fca9e924 tccrun: sort sections
Sort executable before other sections.

Also, apply RUN_SECTION_ALIGNMENT=63 for TCC_TARGET_I386
as well.
2017-02-05 14:00:42 +01:00
grischka
ea2c36c5a9 tccrun: 'selinux' mmap: use only one mapping
In the previous implementation, the rx mapping was never
used.  Therefor it is assumed that it is not needed.

With only one mapping there is no reason to use a real
/tmp/.xxxx file either as we can use an anonymous mapping.
2017-02-05 13:58:14 +01:00
David Mertens
5420bb8a67 SECTION_ALIGNMENT -> RUN_SECTION_ALIGNMENT, and tweaks
Based on feedback from grischka, this commit
(1) updates the name of the alignment constant to be more specific
(2) aligns all sections, including the first (which previosly was
    not aligned)
(3) reduces the x86-64 alignment from 512 to 64 bytes.

The original x86-64 alignment of 512 bytes was based on testing.
After ensuring that the initial section is also aligned, the same
tests indicated that 64 bytes is sufficient.
2017-01-08 07:27:24 -05:00
David Mertens
5d1bc3fbd4 Architecture-specific section alignment
Tests found excessive cache thrashing on x86-64 architectures. The
problem was traced to the alignment of sections. This patch sets up
an architecture-specific alignment of 512 bytes for x86-64 and 16
bytes for all others. It uses preprocessor directives that, hopefully,
make it easy to tweak for other architectures.
2017-01-06 16:56:23 -05:00
Pavlas, Zdenek
0486939291 win32: support "-Wl,--large-address-aware" option 2016-12-30 03:01:33 -08:00
Avi Halachmi (:avih)
9b3e4c5895 tests: don't assume $(CC) is gcc
This also allows self hosting + testing when $(CC) is tcc.
2016-12-24 20:59:10 +02:00
grischka
71c5ce5ced tests: OOT build fixes etc.
tests/Makefile: fix out-of-tree build issues

Also:

- win64: align(16) MEM_DEBUG user memory
  on win64 the struct jmp_buf in the TCCState structure which we
  allocate by tcc_malloc needs alignment 16 because the msvcrt
  setjmp uses MMX instructions.

- libtcc_test.c: win32/64 need __attribute__((dllimport)) for
  extern data objects

- tcctest.c: exclude stuff that gcc does not compile
  except for relocation_test() the other issues are mostly ASM
  related.  We should probably check GCC versions but I have
  no idea which mingw/gcc versions support what and which don't.

- lib/Makefile: use tcc to compile libtcc1.a (except on arm
  which needs arm-asm
2016-12-20 18:05:33 +01:00
Michael Matz
4beb469c91 Fix pseudo leak
Once-allocated buffers (here a string) that aren't explicitely freed
at program end but rather freed at _exit about 1 nanosecond later
are regarded a leak with MEM_DEBUG, so explicitely free it.  Blaeh :-/
2016-12-20 05:42:25 +01:00
Michael Matz
42e2a67f23 Fix some code suppression fallout
Some more subtle issues with code suppression:
- outputting asms but not their operand setup is broken
- but global asms must always be output
- statement expressions are transparent to code suppression
- vtop can't be transformed from VT_CMP/VT_JMP when nocode_wanted

Also remove .exe files from tests2 if they don't fail.
2016-12-20 04:58:34 +01:00
grischka
559ee1e940 i386-gen: fix USE_EBX
Restore ebx from *ebp because alloca might change esp.

Also disable USE_EBX for upcoming release.

Actually the benefit is less than one would expect, it
appears that tcc can't do much with more than 3 registers
except with extensive use of long longs where the disassembly
looks much prettier (and shorter also).

Also: tccgen/expr_cond() : fix wrong gv/save_regs order
2016-12-19 00:33:01 +01:00
grischka
d2332396e4 libtcc.c: -m option cleanup
handle mms-bitfields as sub-options of -m. (-mfloat-abi
is still special because it requires arguments)

tcc.c: help():
- list -mms-bitfields under 'Target specific options'

libtcc.c/MEM_DEBUG
- add check for past buffer writes
2016-12-18 22:57:03 +01:00
grischka
a1c12b9fb9 tests: add memory leak test
Also ...

tcctest.c:
- exclude stuff that gcc doesn't compile on windows.

libtcc.c/tccpp.c:
- use unsigned for memory sizes to avoid printf format warnings
- use "file:line: message" to make IDE error parsers happy.

tccgen.c: fix typo
2016-12-18 22:05:42 +01:00
grischka
f7fc4f02cf tccgen: nocode_wanted++/--
uses 'nocode_wanted' as a level couter instead of
'saved_nocode_wanted' everywhere.
2016-12-18 18:58:33 +01:00
grischka
e5efd18435 tccgen: fix expr_cond for alt. nocode_wanted
making shure that both the active and the passive branches
do exacly the same thing.
2016-12-18 18:55:55 +01:00
grischka
f843cadb6b tccgen: nocode_wanted alternatively
tccgen.c: remove any 'nocode_wanted' checks, except in
- greloca(), disables output elf symbols and relocs
- get_reg(), will return just the first suitable reg)
- save_regs(), will do nothing

Some minor adjustments were made where nocode_wanted is set.

xxx-gen.c: disable code output directly where it happens
in functions:
- g(), output disabled
- gjmp(), will do nothing
- gtst(), dto.
2016-12-18 18:53:21 +01:00
Michael Matz
77d7ea04ac Fix gawk miscompile
See testcase.  Function pointer use was hosed when the destination
function wasn't also called normally by the program.
2016-12-18 05:20:14 +01:00
Michael Matz
cd9514abc4 i386: Fix various testsuite issues
on 32bit long long support was sometimes broken.  This fixes
code-gen for long long values in switches, disables a x86-64 specific
testcase and avoid an undefined shift amount.  It comments out
a bitfield test involving long long bitfields > 32 bit; with GCC layout
they can straddle multiple words and code generation isn't prepared
for this.
2016-12-15 17:53:09 +01:00
Michael Matz
3980e07fe5 arm64: Handle R_AARCH64_PREL32 again
This got lost when splitting reloc handling to individual files.
2016-12-15 17:49:57 +01:00
Michael Matz
b155432b65 arm64: Fix largeptr test
VT_PTR needs to be handled like VT_LLONG.
2016-12-15 17:49:56 +01:00
Michael Matz
b5b12b89a0 arm64: Fix a case of dead code suppression
82_nocode_wanted.c:kb_wait_2_1 was miscompiled on arm64.
2016-12-15 17:49:56 +01:00
Michael Matz
f5ae4daa5f struct-layout: Allow lowering of member alignment
when an alignment is explicitely given on the member itself,
or on its types attributes then respect it always.  Was only
allowed to increase before, but GCC is allowing it.
2016-12-15 17:49:56 +01:00
Michael Matz
8859dc9e6d Support large alignment requests
The linux kernel has some structures that are page aligned,
i.e. 4096.  Instead of enlarging the bit fields to specify this,
use the fact that alignment is always power of two, and store only
the log2 minus 1 of it.  The 5 bits are enough to specify an alignment
of 1 << 30.
2016-12-15 17:49:56 +01:00
Michael Matz
d815a0f658 struct-layout: cleanup code a bit 2016-12-15 17:49:56 +01:00
Michael Matz
23b257a8d2 bitfields: Fix MS layout some more
Another corner case:
  struct foo6_1
  {
    char x;
    short p:8;
    short :0;
    short :0;
    short p2:8;
    char y;
  };

In MS layout the second anon :0 bit-field does _not_ adjust size or
alignment of the struct again.  The first one does, though.
2016-12-15 17:49:56 +01:00
Michael Matz
ed680da951 bitfields: fix PCC layout
Fixes some corner cases in PCC layout.  Testcases coming
up.
2016-12-15 17:49:56 +01:00
Michael Matz
bd69bce20f bitfields: Implement MS compatible layout
Bit-fields are layed out differently in visual C, this implements
a compatible mode.  Checked against Visual C/C++ 2016.
Unfortunately the GCC implementation of MS layout (behind
-mms-bitfields) actually is different, and hence not compatible
with MS in all cases :-/
2016-12-15 17:49:56 +01:00
Michael Matz
78c7096162 Fix struct layout some more
Anonymous sub-sub-members weren't handled correctly.  Bit-fields
neither: this implements PCC layout for now.  It temporarily disables
MS-compatible bit-field layout.
2016-12-15 17:49:56 +01:00
Michael Matz
ddecb0e685 Split off record layouting
Such struct decl:

  struct S { char a; int i;} __attribute__((packed));

should be accepted and cause S to be five bytes long (i.e.
the packed attribute should matter).  So we can't layout
the members during parsing already.  Split off the offset
and alignment calculation for this.
2016-12-15 17:49:56 +01:00
Michael Matz
5d6a9e797a x86-asm: Fix segfault
We need to access cur_text_section, not text_section.
2016-12-15 17:49:56 +01:00
Michael Matz
22f5fccc2c Fix 64bit enums and switch cases
See testcases.  We now support 64bit case constants.  At the same time
also 64bit enum constants on L64 platforms (otherwise the Sym struct
isn't large enough for now).  The testcase also checks for various
cases where sign/zero extension was confused.
2016-12-15 17:49:56 +01:00
Michael Matz
3e77bfb6e9 tccpp: Fix token pasting
See testcase.  We must always paste tokens (at least if not
currently substing a normal argument, which is a speed optimization
only now) but at the same time must not regard a ## token
coming from argument expansion as the token-paste operator, nor
if we constructed a ## token due to pasting itself (that was already
checked by pp/01.c).
2016-12-15 17:49:56 +01:00
Michael Matz
3db037387c libtcc1: Don't use stdlib functions
libtcc1 is the compiler support library and therefore needs
to function in a freestanding environment.  In particular
it can't just use fprintf or stderr, which it was on x86-64
(but only when compiled by GCC).  The tight integration between
libtcc1 and tcc itself makes it impossible to ever reach that
case so the abort() there is enough.  abort() is strictly speaking
also not available in a freestanding environment, but it often is
nevertheless.
2016-12-15 17:49:56 +01:00
Michael Matz
d042e71e9f Fix miscompile with dead switches
In certain very specific situations (involving switches
with asms inside dead statement expressions) we could generate
invalid code (clobbering the buffer so much that we generated
invalid instructions).  Don't emit the decision table if the
switch itself is dead.
2016-12-15 17:49:55 +01:00
Michael Matz
7ae35bf1bb Handle multiple -O options
the last one wins, i.e. "-O2 -O0" does _not_ set __OPTIMIZ__.
2016-12-15 17:49:55 +01:00
Michael Matz
a158260e84 build: Respect CPPFLAGS override
so that e.g. make CPPFLAGS=-DSOMETHING works.
2016-12-15 17:49:55 +01:00
Michael Matz
235711f3d3 64bit: Fix addends > 32 bits
If a symbolic reference is offsetted by a constant > 32bit
the backends can't deal with that, so don't construct such
values.
2016-12-15 17:49:55 +01:00
Michael Matz
a2a596e767 x86-64-asm: Accept high register in clobbers
The callee saved registers (among them r12-r15) really need
saving/restoring if mentioned in asm clobbers, even if TCC
itself doesn't use them.  E.g. the linux kernel relies on that
in its switch_to() implementation.
2016-12-15 17:49:55 +01:00
Michael Matz
ddd461dcc8 Fix initializing members multiple times
When intializing members where the initializer needs relocations
and the member is initialized multiple times we can't allow
that to lead to multiple relocations to the same place.  The last
one must win.
2016-12-15 17:49:53 +01:00
Michael Matz
f081acbfba Support local register variables
Similar to GCC a local asm register variable enforces the use of a
specified register in asm operands (and doesn't otherwise
matter).  Works only if the variable is directly mentioned as
operand.  For that we now generally store a backpointer from
an SValue to a Sym when the SValue was the result of unary()
parsing a symbol identifier.
2016-12-15 17:47:13 +01:00
Michael Matz
3bc9c325c5 Fix const folding of 64bit pointer constants
See testcase.
2016-12-15 17:47:12 +01:00
Michael Matz
0b0e64c2c9 x86-asm: Correct register size for pointer ops
A pointer is 64 bit as well, so it needs a full
register for register operands.
2016-12-15 17:47:12 +01:00
Michael Matz
7ab35c6265 struct-init: Copy relocs for compound literals
When copying the content of compound literals we must
include relocations as well.
2016-12-15 17:47:12 +01:00
Michael Matz
0bca6cab06 x86_64-asm: fix copy-out registers
If the destination is an indirect pointer access (which ends up
as VT_LLOCAL) the intermediate pointer must be loaded as VT_PTR,
not as whatever the pointed to type is.
2016-12-15 17:47:12 +01:00
Michael Matz
ad723a419f x86_64: Add -mno-sse option
This disables generation of any SSE instructions (in particular
in stdarg function prologues).  Necessary for kernel compiles.
2016-12-15 17:47:12 +01:00
Michael Matz
b5669a952b x86-64: relocation addend is 64bit
Some routines were using the wrong type (int) in passing addends,
truncating it.  This matters when bit 31 isn't set and the high
32 bits are set: the truncation would make it unsigned where in
reality it's signed (happen e.g. on the x86-64 with it's load
address at top-2GB).
2016-12-15 17:47:12 +01:00
Michael Matz
975c74c1f5 x86-64: Prefer 32S relocations
This target has _32 and _32S relocs (the latter being for signed
32 bit entities).  All instruction displacements have to use
the 32S variants.  Normal references like
  .long s
normally would use the _32 variant.  For normal executables this
doesn't matter.  For shared libraries neither (which use PC-relative
relocs).  But it matters for things like the kernel that are linked
to high addresses (signed ones).  There the GNU linker would error
out on overflow for the _32 variant.

To keep life simple we simply switch from _32 to _32S altogether.
Strictly speaking it's still wrong, but in practice using _32 is
more often wrong than using _32S ;)
2016-12-15 17:47:12 +01:00
Michael Matz
ad8e14b740 opt: Don't emit inline functions from dead code
Inside dead code don't regard inline functions as being
referenced.
2016-12-15 17:47:12 +01:00
Michael Matz
ce55d03eef Handle __builtin_extract_return_addr
Our architectures don't need anything special for this
builtin, just pass through the argument.
2016-12-15 17:47:12 +01:00
Michael Matz
fb933ae0eb opt: constprop also 'cond && 0'
We didn't handle constants in logical expressions when they weren't
the first operand.  Some reordering in the loop structure is enough
to handle them.
2016-12-15 17:47:12 +01:00
Michael Matz
ca435dc2e3 opt: Make break and goto not fallthrough
As we can optimize dead code a bit already it's fitting
to disable code emission after break and goto.
2016-12-15 17:47:12 +01:00
Michael Matz
31c7ea0165 opt: Start optimizing dead code a bit
If a condition is always zero/non-zero we can omit the
then or else code.  This is complicated a bit by having to
deal with labels that might make such code reachable without
us yet knowing during parsing.
2016-12-15 17:47:12 +01:00
Michael Matz
b303a00ce0 Revert "Reject jumping inside stmtexprs"
Not fully thought out.  You can't jump inside stmt exprs,
but you can jump out of them.  So there's a difference
between undefined but declared labels at the end of stmt
exprs and those defined inside.  Additionally it should
also be checked if a label defined inside a stmt expr
was tentatively created as declared from outside.

I'm not prepared doing that right now, so simply revert.

This reverts commit 9160e4cab9147d77840cc44a285031fdb4640cf9.
2016-12-15 17:47:11 +01:00
Michael Matz
d4d3144e75 Factor out const condition detection
Creating condition_3way for this.
2016-12-15 17:47:11 +01:00
Michael Matz
892c3d996f Reject jumping inside stmtexprs
One can't jump into statement expressions from outside
them, like the following:

  int i = ({ label: foo(); 42; });
  goto label;

We reject this by making the labels simply not available
outside (GCC has a nicer error message about jumping into
a statement expression).
2016-12-15 17:47:11 +01:00
Michael Matz
1602998751 Fix more nocode_wanted jump problems
In statement expression we really mustn't emit backward jumps
under nocode_wanted (they will form infinte loops as no expressions
are evaluated).  Do-while and explicit loop with gotos weren't
handled.
2016-12-15 17:47:11 +01:00
Michael Matz
f2a071e808 Fix aliases on 64 bit
Use correct width ELF structure.
2016-12-15 17:47:11 +01:00
Michael Matz
9656560f14 Fix sizeof(char[a])
The sizes of VLAs need to be evaluated even inside sizeof,
i.e. when nocode_wanted is set.
2016-12-15 17:47:11 +01:00
Michael Matz
49bb5a7e06 Fix __builtin_constant_p(1000/x)
was incorrectly treated as constant because the vpop removed
all traces of non-constness.
2016-12-15 17:47:11 +01:00
Michael Matz
5bd8aeb917 tccasm: Support refs to anon symbols from asm
This happens when e.g. string constants (or other static data)
are passed as operands to inline asm as immediates.  The produced
symbol ref wouldn't be found.  So tighten the connection between
C and asm-local symbol table even more.
2016-12-15 17:47:11 +01:00
Michael Matz
dd57a34866 tccasm: Don't ignore # in preprocessor directives
Our preprocessor throws away # line-comments in asm mode.
It did so also inside preprocessor directives, thereby
removing stringification.  Parse defines in non-asm mode (but
retain '.' as identifier character inside macro definitions).
2016-12-15 17:47:11 +01:00
Michael Matz
e7ef087598 x86-asm: Accept all 32bit immediates
In particular don't care if they're signed or unsigned, they're all
acceptable as immediates.
2016-12-15 17:47:11 +01:00
Michael Matz
372f4b6a4e Fix enum bitfields passed to stdarg functions
VT_ENUM types use the .ref member and can be VT_BITFIELD,
so we need to copy it as well.  Simply do it always.
2016-12-15 17:47:11 +01:00
Michael Matz
d720865fb6 Addresses of non-weak symbols are non-zero
Use this fact in some foldings of comparisons.  See testcase.
2016-12-15 17:47:10 +01:00
Michael Matz
be6d8ffc10 Fix access-after-free with statement expressions
The return value of statement expressions might refer to local
symbols, so those can't be popped.  The old error message always
was just a band-aid, and since disabling it for pointer types it
wasn't effective anyway.  It also never considered that also the
vtop->sym member might have referred to such symbols (see the
testcase with the local static, that used to segfault).

For fixing this (can be seen better with valgrind and SYM_DEBUG)
simply leave local symbols of stmt exprs on the stack.
2016-12-15 17:47:10 +01:00
Michael Matz
d0d25ec7df tccpp: Allow computed include like 42.h
The include directive needs to be parsed as pp-tokens, not
as token (i.e. no conversion to TOK_STR or TOK_NUM).  Also fix
parsing computed includes using quoted strings.
2016-12-15 17:47:10 +01:00
Michael Matz
0381387640 x86-asm: Correctly infer register size for bools
Register operands of type _Bool weren't correctly getting
the 8-bit sized registers (but rather used the default 32-bit
ones).
2016-12-15 17:47:10 +01:00
Michael Matz
9e0af6d2b5 x86-64-asm: Implement cmpxchg16b 2016-12-15 17:47:10 +01:00
Michael Matz
ca8c1cd643 x86-64: Allow loads from some structs/unions
GCC allows register loads for asms based on type mode,
and correctly sized structs/union have an allowed mode
(basically 1,2,4,8 sized aggregates).
2016-12-15 17:47:10 +01:00
Michael Matz
9ae10cad1f tccasm: Lookup C symbols from ASM blocks
It's now possible to use symbols defined in C code to be used
from later inline asm blocks.  See testcase.
2016-12-15 17:47:10 +01:00
Michael Matz
c4edfb4e08 tccasm: Implement .set sym, expr
That, as well as "sym = expr", if expr contains symbols.
Slightly tricky because a definition from .set is overridable,
whereas proper definitions aren't.

This doesn't yet allow using this for override tricks from C
and global asm blocks because the symbol tables from C and asm
are separate.
2016-12-15 17:47:10 +01:00
Michael Matz
34fc6435ee enums and ints are compatible
But like GCC do warn about changes in signedness.  The latter
leads to some changes in gen_assign_cast to not also warn about
  unsigned* = int*
(where GCC warns, but only with extra warnings).
2016-12-15 17:47:10 +01:00
Michael Matz
b1a906b970 enums and ints are compatible 2016-12-15 17:47:10 +01:00
Michael Matz
c0368604e1 x86-64-asm: Fix ltr/str and push/pop operands
str accepts rm16/r32/r64, and push/pop defaults to 64 when given
memory operands (to 32 on i386).
2016-12-15 17:47:10 +01:00
Michael Matz
45b24c37a0 x86-64-asm: Implement high %cr registers 2016-12-15 17:47:09 +01:00
Michael Matz
4e46c22d5c struct-init: Support range inits for local vars
Implement missing support for range init for local variables.
2016-12-15 17:47:09 +01:00
Michael Matz
4cb7047f0f x86-64-asm: Support high registers %r8 - %r15
This requires correctly handling the REX prefix.
As bonus we now also support the four 8bit registers
spl,bpl,sil,dil, which are decoded as ah,ch,dh,bh in non-long-mode
(and require a REX prefix as well).
2016-12-15 17:47:09 +01:00
Michael Matz
8765826465 inline-asm: Accept "flags" clobber 2016-12-15 17:47:09 +01:00
Michael Matz
b7ca74577b struct-init: Allow member initialization from qualified lvalues
See testcase.
2016-12-15 17:47:09 +01:00
Michael Matz
9e86ebee94 struct-init: Correctly parse unnamed member initializers
For
  union U { struct {int a,b}; int c; };
  union U u = {{ 1, 2, }};
The unnamed first member of union U needs to actually exist in the
structure so initializer parsing isn't confused about the double braces.
That means also the a and b members must be part of _that_, not of
union U directly.  Which in turn means we need to do a bit more work
for field lookup.

See the testcase extension for more things that need to work.
2016-12-15 17:47:09 +01:00
Michael Matz
21da73c383 struct-init: Cleanup some more
Some parameters aren't actually necessary.  Also join the
two parsing loops for the initializer list of arrays and structs.
2016-12-15 17:47:09 +01:00
Michael Matz
7bf323843e struct-init: Cleanup
Remove dead code and variables.  Properly check for unions when
skipping fields in initializers.  Make tests2/*.expect depend
on the .c files so they are automatically rebuilt when the latter
change.
2016-12-15 17:47:09 +01:00
Michael Matz
ed7d54651d struct-init: Implement initializing subaggregates
E.g. "struct { struct S s; int a;} = { others, 42 };"
if 'others' is also a 'struct S'.  Also when the value is a
compound literal.  See added testcases.
2016-12-15 17:47:09 +01:00
Michael Matz
968bccdd2a struct-init: Reimplement
Start reimplementing the whole initializer handling to be
conforming to ISO C.  This patch just reimplements current
functionality to prepare for further changes, all tests pass.
2016-12-15 17:47:09 +01:00
Michael Matz
5d0c16a884 Support attribute between double pointer stars
"int * __attribute__((something)) *" is supported by GCC.
2016-12-15 17:47:09 +01:00
Michael Matz
662338f116 Fix function to pointer conversion
This snippet is valid:
  void foo(void);
  ... foo + 42 ...
the function designator is converted to pointer to function
implicitely.  gen_op didn't do that and bailed out.
2016-12-15 17:47:08 +01:00
Michael Matz
e034853b38 Fix parsing array typedefs of unknown size
This must compile:
 typedef int arrtype1[];
 arrtype1 sinit19 = {1};
 arrtype1 sinit20 = {2,3};
and generate two arrays of one resp. two elements.  Before the fix
the determined size of the first array was encoded in the type
directly, so sinit20 couldn't be parsed anymore (because arrtype1
was thought to be only one element long).
2016-12-15 17:47:08 +01:00
Michael Matz
b7e0b693a6 tccpp: Implement __BASE_FILE__ macro
Like __FILE__ but always refers to the command line file name also
from inside headers.
2016-12-15 17:47:08 +01:00
Michael Matz
8a1a2a6033 Implement __builtin_choose_expr
Follows GCC implementation.
2016-12-15 17:47:08 +01:00
Michael Matz
10e4db45dc x86-asm: Implement prefetchw opcode 2016-12-15 17:47:08 +01:00
Michael Matz
5692716770 x86-asm: Fix lar opcode operands
lar can accept multiple sizes as well (wlx), like lsl.  When using
autosize it's important to look at the destination operand first;
when it's a register that one determines the size, not the input
operand.
2016-12-15 17:47:08 +01:00
Michael Matz
e3f2a68311 tcc-asm: Parse .size directive correctly
When the .size directive was closed with a ';' tcc eat everything after
it up to lineend.
2016-12-15 17:47:08 +01:00
Michael Matz
6a5ec8cb3c x86-asm: More opcodes
Some new opcodes and some aliases: ljmp[wl], prefetch{nta,t0,t1,t2},
bswap[lq], sysretq, swapgs.
2016-12-15 17:47:08 +01:00
Michael Matz
d9d029006c x86-asm: Add [sl][ig]dtq opcodes
GAS has alias lgdtq for lgdt (similar for saves and GDT).  It doesn't
have the same for LDT.
2016-12-15 17:47:08 +01:00
Michael Matz
75e8df126f inline asm: Accept 'R' constraint
This is like 'r' but only accepts the eight legacy regs.  Currently
that's the same as 'r' because we don't support the high ones.
2016-12-15 17:47:08 +01:00
Michael Matz
f6c1eb10e2 x86-asm: Implement fxrstorq and fxsaveq 2016-12-15 17:47:08 +01:00
Michael Matz
2b618c1ab4 Fix parsing attributes for struct decls
Given this code:

  struct __attribute__((...)) Name {...};

TCC was eating "Name", hence generating an anonymous struct.
It also didn't apply any packed attributes to the parsed
members.  Both fixed.  The testcase also contains a case
that isn't yet handled by TCC (under a BROKEN #define).
2016-12-15 17:47:08 +01:00
Michael Matz
7e51546624 x86-asm: Implement clflush opcode 2016-12-15 17:47:08 +01:00
Michael Matz
e5f4f8d0e7 inline asm: Accept "e" constraint
This is meant to be a (sign-extended) 32bit constant (possibly
symbolic).  We don't do any checks and simply regard it as "i".
2016-12-15 17:47:08 +01:00
Michael Matz
bbce31552e inline asm: accept concatenated strings in constraints
This really should be handled implicitly in the preprocessor,
but for now this is enough.
2016-12-15 17:47:08 +01:00
Michael Matz
f9423ff3fa inline asm: Fix 'P' and accept some r<nr> registers
A 'P' template modifier should avoid adding a '$' to literal
arguments.  Also accept the numbered r8+ registers in an inline
asm clobber list (ignoring them for now).
2016-12-15 17:47:07 +01:00
Michael Matz
10c3514889 Accept symbols in initializers also on 64 bit
Those should use long or long long type, and generate a 64bit reloc.
2016-12-15 17:47:07 +01:00
Michael Matz
920474115c x86-64-asm: More opcodes
Implement some more opcodes, syscall, sysret, lfence, mfence, sfence.
2016-12-15 17:47:07 +01:00
Michael Matz
1a5eacb445 tccasm: Implement compare expressions
I.e. implement < > <= >= == !=.  Comparisons are signed and result
is -1 if true, 0 if false.
2016-12-15 17:47:07 +01:00
Michael Matz
ff5561ff7d x86-64-asm: Accept expressions for .quad
The x86-64 target has 64bit relocs, and hence can accept
generic expressions for '.quad'.
2016-12-15 17:47:07 +01:00
Michael Matz
253afeed1e inline asm: Accept 'p' constraint and 'P' template mod
'p' is conservatively the same as 'r' and 'P' as template
modifier can be ignored in TCC.
2016-12-15 17:47:07 +01:00
Michael Matz
63e3ff7cca tccasm: Accept .balign 2016-12-15 17:47:07 +01:00
Michael Matz
8e4da42384 Accept more asm expressions
In particular subtracting a defined symbol from current section
makes the value PC relative, and .org accepts symbolic expressions
as well, if the symbol is from the current section.
2016-12-15 17:47:07 +01:00
Michael Matz
c82e52d55b tccasm: Implement .pushsection and .popsection 2016-12-15 17:47:06 +01:00
Michael Matz
6763b02abc Accept empty struct member decls
struct S { /*nothing*/; int a; };

is an acceptable struct declaration, there may be stray semicolons
in the member list.
2016-12-15 17:47:06 +01:00
Michael Matz
d5d881d9e9 x86-asm: Accept 'q' modifier
In inline extended asm '%q1' refers to the 64bit register of operand 1.
2016-12-15 17:47:06 +01:00
Michael Matz
8531de319a Accept concatenated strings in attributes
attribute(section("one" "two")) should be accepted (the section
name being "onetwo"), it's normal string concatenation.
2016-12-15 17:47:06 +01:00
Michael Matz
b6799ccd2e Accept -Wp,args
These are preprocessor cmdline arguments, but even in GCC they
aren't specified but rather left as being subject to changes.
Nobody should use them, but let's to a half-assed attempt
at accepting them.
2016-12-15 17:47:06 +01:00
Michael Matz
2b3c7d2287 Change dependency file format a bit
The linux fixdep parse is very stupid and only recognizes
a target token when ':' is part of it.  A space is permitted
in Makefile syntax, but it's easier to change our emitter
than all fixdep parsers out there.
2016-12-15 17:47:06 +01:00
Michael Matz
b285fc50f3 Add --param, reject -mARG if ARG not 32 or 64 2016-12-15 17:47:06 +01:00
Michael Matz
9285149548 Implement -include cmdline option
This option includes a file as if '#include "file"' is the first
line of compiled files.  It's processed after all -D/-U options
and is processed per input file.
2016-12-15 17:47:06 +01:00
Michael Matz
21d2b71b5c Free defines before gen_inline_functions
gen_inline_functions uses the macro facilities of the preprocessor,
which would interact when macros would still be defined in a
different pre-processor implementation I'm working on.
So always free defines before generating inline functions, they
are all macro expanded already.
2016-12-15 17:47:06 +01:00
Michael Matz
38e5cf0983 tccpp: Fix macro_is_equal
When tokens in macro definitions need cstr_buf inside get_tok_str,
the second might overwrite the first (happens when tokens are
multi-character non-identifiers, see testcase) in macro_is_equal,
failing to diagnose a difference.  Use a real local buffer.
2016-12-15 17:47:05 +01:00
Michael Matz
8080401ab0 tccpp: free defines also with PP_BENCH
When benchmarking preprocessing of multiple files we need to
free the defines like when not benchmarking.
2016-12-15 17:47:05 +01:00
Michael Matz
e2f489aaff x86-asm: Get rid of OPC_JMP and OPC_SHORTJMP
Those two insn types are nicer to handle as operand types, because
the pressure for bits on instr_type is higher than for operands.
2016-12-15 17:47:05 +01:00
Michael Matz
4094f7c5fc x86-64-asm: Tidy 2016-12-15 17:47:05 +01:00
Michael Matz
58963828ab x86-asm: Correct mem64->xmm movq
Now we can express prefixes with 0x0fxx opcodes we can correct the
movq mem64->xmm opcode, and restrict the movq xmm->mem64 movq to
not invalidly accept mmx.
2016-12-15 17:47:05 +01:00
Michael Matz
5a222588a8 x86-asm: Remove OPC_D16
Now that we can store prefixes even for 0x0fXX opcodes we can remove
the OPC_D16 bit.
2016-12-15 17:47:05 +01:00
Michael Matz
8a10a442ff x86-asm: Fix register order
Inserting random registers in the middle of the 8-blocks
breaks register assignment.
2016-12-15 17:47:05 +01:00
Michael Matz
bde802df29 x86-asm: Reorganize instr_type
Disjoint instruction types don't need to be a bit field, so
introduce an enumeration (3 bits).  Also the 0x0f prefix can
be expressed by a bit, doesn't need a byte in the opcode field.
That enables to encode further prefixes still in 16 bit.
To not have to touch all insns do some macro fiddling filtering
out a 0x0f byte in the second position.
2016-12-15 17:47:05 +01:00
Michael Matz
4af6e087dd x86-asm: move stats code
The old place (tccasm.c) didn't have access to the variables anymore
and was ifdefed out.  Move it to i386-asm.c.
2016-12-15 17:47:05 +01:00
Michael Matz
ed35ac841b x86-asm: Add more SSE2 instructions
In particular those that are extensions of existing mmx (or sse1)
instructions by a simple 0x66 prefix.  There's one caveat for
x86-64: as we don't yet correctly handle the 0xf3 prefix
the movq mem64->xmm is wrong (tested in asmtest.S).  Needs
some refactoring of the instr_type member.
2016-12-15 17:47:05 +01:00
grischka
2b7ee000cd tests: add .so/.dll creation test
Also remove bitfield test from tcctest.c because gcc
versions don't agree among each other.
2016-12-15 17:04:07 +01:00
grischka
ca92bfc3c6 tccelf: some linker cleanup
- generate and use SYM@PLT for plt addresses
- get rid of patch_dynsym_undef hack (no idea what it did on FreeBSD)
- use sym_attrs instead of symtab_to_dynsym
- special case for function pointers into .so on i386
- libtcc_test: test tcc_add_symbol with data object
- move target specicic code to *-link.c files
- add R_XXX_RELATIVE (needed for PE)
2016-12-15 17:01:22 +01:00
Thomas Preud'homme
fe6453f8f0 Use functions to get relocation info
MSVC does not support array designator so cannot compile source using
relocs_info. This commit replace the relocs_info array into a set of
functions, each returning the value given by a given field of the struct
reloc_info.
2016-12-10 18:14:10 +00:00
Thomas Preud'homme
d31226c873 Remove now useless pltoff_addend reloc info
Last use for pltoff_addend field of relocs_info array was removed in
commit 25927df3b7. It is now useless so
this commit removes it and all initialization related to it.
2016-12-10 18:13:23 +00:00
Thomas Preud'homme
ee2108d07d Add missing relocation info for C67 target
Fill in relocs_info table for C67 and fix R_C60_NUM value to really be
greater than all relocation values known to TCC.
2016-12-10 17:31:20 +00:00
Thomas Preud'homme
11747fe5d0 Error out in put_got_entry if no dynamic symbol 2016-12-10 19:22:02 +08:00
Thomas Preud'homme
dfed9babfc Allow PLT/GOT entry for weak static symbol 2016-12-10 19:12:36 +08:00
Thomas Preud'homme
0bf262864c Fix PLT creation for i386
i386 target does not have PC relative loads. Its ABI therefore require
ebx register to points to the GOT when executing a PLT entry. This means
that PLT entry cannot be used transparently, the compiler needs to
expect execution of a PLT entry to be able to use one, that is a PLT
entry should only be created if the relocation explicitely asks for it
(eg. R_386_PLT32).

This patch creates a new target macro PCRELATIVE_DLLPLT to indicate
whether a target can do a PC relative load in PLT entry when building a
dynamic library. Executable do not normally pose a problem because they
are loaded at a fixed address and thus the absolute address of GOT can
be used.

Note that in such a case, if the compiler does not use a PLT aware
relocation for external access then the code relocation will fall on the
dynamic loader since there is no PLT entry to relocate too.
2016-12-10 09:44:09 +00:00
Edmund Grimley Evans
e0fe69050d arm64: Fix regression introduced by 6245db9. 2016-12-05 23:29:25 +00:00
Thomas Preud'homme
2372639e9d Fix set but not used error in arm64-link.c 2016-12-05 21:34:30 +00:00
Thomas Preud'homme
3811794048 Fix tcc_error params for R_AARCH64_(JUMP|CALL)26 2016-12-05 21:34:30 +00:00
Thomas Preud'homme
e22249b81c Error on unrecognized relocations 2016-12-05 20:58:00 +00:00
Thomas Preud'homme
557c5c1f11 Add relocs_info array to c67 backend 2016-12-05 20:52:02 +00:00
Thomas Preud'homme
59391d5520 Fix relocs_info declaration in tcc.h
C standard specifies that array should be declared with a non null size
or with * for standard array. Declaration of relocs_info in tcc.h was
not respecting this rule. This commit add a R_NUM macro that maps to the
R_<ARCH>_NUM macros and declare relocs_info using it. This commit also
moves all linker-related macros from <arch>-gen.c files to <arch>-link.c
ones.
2016-12-05 20:51:10 +00:00
Thomas Preud'homme
097cf3aa5e Control symbol table of which to relocate symbols
Pass pointer to symbol table to relocate the symbols of in relocate_syms
2016-12-03 17:26:51 +00:00
Thomas Preud'homme
c4bec037be Code simplification in relocate_syms 2016-12-03 17:26:51 +00:00
Thomas Preud'homme
25927df3b7 Consolidate all relocations in relocate_section
Static relocation of functions in dynamic libraries must use the PLT
entry as the target. Before this commit, it used to be done in 2 parts
for ARM, with the offset of the PLT entry from the beginning of the PLT
being put in the relocated place in build_got_entries () and then the
address of the PLT being added in relocate_section.

This led to code dealing with reading the offset of a bl instruction in
build_got_entries. Furthermore, the addition of the address of the start
of the PLT was done based on the relocation type which does not convey
whether a PLT entry should be used to reach the symbol.

This commit moves the decision to use the PLT as the target in
relocate_section, therefore having the instruction aware code contained
to the target-specific bit of that function (in <target>-link.c).

Note that relocate_syms is *not* the right place to do this because two
different relocations for the same symbol can make different decision.
This is the case in tcc -run mode where the static and dynamic
relocation are done by tcc.

Storing the PLT entry address in the symbol's st_value field and relying
on the specific relocation type being used for dynamic relocation would
work but the PLT entry address would then appear in the static symbol
table (symtab). This would also make the static symbol table entry
differ from the dynamic symbol table entry.
2016-12-03 17:26:51 +00:00
Thomas Preud'homme
2c38800bbe Allow to get sym attr and fail if no entry
Change alloc_sym_attr into get_sym_attr and add a parameter to control
whether to allocate a new symattr structure or return NULL if symbol is
not found;
2016-12-03 17:26:51 +00:00
Thomas Preud'homme
a11b0a67e3 Consolidate GOT creation in build_got_entries
Currently GOT/PLT creation happens in two locations depending on whether
the GOT/PLT [entry] is required by the symbol or the relocation:

- bind_exe_dynsym for relocations to undefined symbol
- build_got_entries/put_got_entry for relocations that require a GOT/PLT
  entry

This commit consolidate GOT/PLT creation in build_got_entries by
reducing bind_exe_dynsym's job to create a dynamic symbol for undefined
symbols. build_got_entries then invoke put_got_entry if the symbol being
relocated is undefined or the relocation asks for a PLT or GOT [entry].
put_got_entry is also modified to only export a symbol in the dynamic
symbol table when we are in the case of PLT/GOT [entry] required by the
relocation (since undefined symbol are already exported by
bind_exe_dynsym).
2016-12-03 17:26:51 +00:00
Thomas Preud'homme
1c811a4d1d Make build_got_entries more target independent
Factor most of common logic between targets in build_got_entries by
defining target specific info into structures in the backends.
2016-12-03 17:26:51 +00:00
Thomas Preud'homme
523b55d82d Only create GOT or GOT entry when needed
Currently we always build a GOT when we recognize a relocation in
build_got_entries even if the relocation does not require one. In the
same spirit, when the relocation does require one we always create a GOT
entry even if not entry is necessary. This patch restricts the creation
of a GOT and a GOT entry to relocations that needs it, ie:
- do not create a GOT if relocation is not related to GOT and symbol is
  not UNDEF
- do not create a GOT entry if relocation only relates to beginning of
  GOT
2016-12-03 17:26:51 +00:00
Thomas Preud'homme
6cd23d1d8c Recognize more relocations as needing GOT/PLT entry 2016-12-03 17:26:51 +00:00
Thomas Preud'homme
cb273fdad8 Do section relocation in architecture backend 2016-12-03 17:26:51 +00:00
Thomas Preud'homme
60374d01ae Add address of GOT + 8 in PLT + 16 and fix PLT0
On ARM targets, the jump to ld.so resolution routine is done in PLT0 by
loading the offset to the GOT found in PLT+16 and from there loading the
address in GOT+8 and jumping to it.

Currently tcc starts the first regular PLT entry at PLT+16 which thus
does not contain the offset to the GOT. This commit fixes that.

Note that calls via PLT still worked nonetheless because of some missing
dynamic tag which makes ld.so behaves as if RTLD_BIND_NOW was specified
in the environment for all executable created by tcc.
2016-12-03 17:26:51 +00:00
Thomas Preud'homme
f924d0ca96 Improve put_got_entry doc and structure 2016-12-03 17:26:51 +00:00
Thomas Preud'homme
64b5ee2dea Rename add_elf_sym to set_elf_sym
add_elf_sym is a confusing name because it is not clear what the
function does compared to put_elf_sym. As a matter of fact, put_elf_sym
also adds a symbol in a symbol table. Besides, "add_elf_sym" fails to
convey that the function can be used to update a symbol (for instance
its value). "set_elf_sym" seems like a more appropriate name: it will
set a symbol to a given set of properties (value, size, etc.) and create
a new one if non exist for that name as one would expect.
2016-12-03 17:26:51 +00:00
Thomas Preud'homme
9e6610b0aa Improve comments for symbol export and binding 2016-12-03 17:26:51 +00:00
Thomas Preud'homme
e9769a7249 Do not add symbol if it is already there
Do not create a new symbol in add_elf_sym if a symbol with same properties
(value, size, info, etc.) already exists. This prevents symbols from
being exported twice in the dynamic symbol table.
2016-12-03 17:26:51 +00:00
Thomas Preud'homme
bf692af31b Fix error logic for undefined reference in library
Prior to this patch, an error would only be given when a library has an
unresolved undefined symbol if there is no undefined reference for the
same symbol in the executable itself. This patch changes the logic to
check both that the executable has the symbol in its static symbol table
*and* that it is defined to decide if the error path should be followed.
2016-12-03 17:26:51 +00:00
root
ccf9ed7d54 Clear SHF_GROUP flag when linking
SHF_GROUP flag set on a section indicates that it is part of a section
group and that if the section is removed, the other sections in the same
group should be removed as well [1]. Since section group are guide for
the linking process, they do not have any meaning after linking has
occured. TCC rightfully [2] discard such sections (by not recognizing the
section type) but keeps the SHF_GROUP flag set on sections that were
part of a section group which confuses binutils (objdump and gdb at
least). Clearing that bit makes objdump and gdb accept binaries created
by TCC.

[1] https://docs.oracle.com/cd/E19683-01/816-1386/chapter7-26/index.html
[2] GNU ld does the same
2016-12-03 17:26:50 +00:00
Christian Jullien
ed99f3608d Remove warning when __builtin_frame_address is used with gcc >= 6. 2016-11-30 06:18:48 +01:00
David Mertens
d2e2f42382 Implement gcc bitfield algorithm; add -mms-bitfields 2016-11-28 09:01:12 -05:00
David Mertens
3c68a8c6c0 Minor grammar fixes to docs 2016-11-28 08:59:53 -05:00
grischka
0d14e7e698 configure: prefer lib64 on 64-bit platforms
use lib64 if
- "/usr/lib/multi-arch-triplet" does not work and
- we are on a 64-bit platform and
- lib64 exists and does contain crti.o
2016-11-28 14:48:54 +01:00
grischka
a52a39179a tccelf: introduce add32/64le() 2016-11-20 14:52:56 +01:00
grischka
4a3741bf02 x86_64-asm: =m operand fixes
The problem was with tcctest.c:

    unsigned set;
    __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");

when with tcc compiled with the HAVE_SELINUX option, run with
tcc -run, it would use large addresses far beyond the 32bits
range when tcc did not use the pc-relative mode for accessing
'set' in global data memory.  In fact the assembler did not
know about %rip at all.

Changes:
- memory operands use (%rax) not (%eax)
- conversion from VT_LLOCAL: use type VT_PTR
- support 'k' modifier
- support %rip register
- support X(%rip) pc-relative addresses

The test in tcctest.c is from Michael Matz.
2016-11-20 14:50:56 +01:00
Thomas Stalder
47fd807f9b arm: Fix relocate_section with TCC_OUTPUT_MEMORY 2016-11-13 11:52:28 +01:00
Thomas Stalder
4af25aed92 remove warnings 2016-11-13 11:45:55 +01:00
grischka
59216d3db0 tccgen: fix inline_functions double free fix 2016-11-11 20:25:13 +01:00
grischka
7c28c9b13f tccgen: inline_functions double free fix
Fix double free of the inline function token_string which
could happen when an error/longjmp occurred while compiling
the inline function.
2016-11-11 18:29:45 +01:00
Pavlas, Zdenek
7e7f2e5d1b bcheck: access fields of local structs w/o bcheck
Revert previous commit, this is probably a better fix.
2016-11-10 05:15:07 -08:00
Pavlas, Zdenek
550e861bf7 bcheck: add structs to local regions
int test()
{
  struct { int i; } s = { 42 };
  return s.i; // bound checked
}
2016-11-09 04:11:40 -08:00
Pavlas, Zdenek
cdf715a0b5 i386 + bcheck: fix __bound_local_new
With -b, this produces garbage. Code to call __bound_local_new
is put at wrong place, overwriting the regparam setup code.
Fix copied from x86_64-gen.c.

void __attribute__((regparm(3)))
fun(int unused)
{
  char local[1];
}
2016-11-09 01:04:45 -08:00
grischka
3054a76249 i386-gen: use EBX as 4th register
May be enabled/disabled by changing this line:
    #define USE_EBX 1
2016-10-19 19:22:15 +02:00
grischka
02642bc94c lib/libtcc1.c: cleanup
- remove #include dependencies from libtcc1.c
  for easier cross compilation
- clear_cache only on ARM
- error-message for mprotect failure
2016-10-19 19:21:36 +02:00
grischka
bfd1c08d6c tccrun/win64: cleanup runtime function table
- call RtlDeleteFunctionTable
  (important for multiple compilations)

- the RUNTIME_FUNCTION* is now at the beginning of the
  runtime memory.  Therefor when tcc_relocate is called
  with user memory, this should be done manually before
  it is free'd:
      RtlDeleteFunctionTable(*(void**)user_mem);
      [ free(user_mem); ]

- x86_64-gen.c: expand char/short return values to int
2016-10-19 19:21:27 +02:00
grischka
02919cd275 configure: --triplet= option, Makefile: cleanup 2016-10-17 23:24:10 +02:00
grischka
0be098929a tccpp_new/delete and other cleanups 2016-10-17 23:24:01 +02:00
Michael Matz
6fbcc14a5d system-hacks: define __GNUC__ for FreeBSD
FreeBSDs system headers contain unconditional usage of
macros like __aligned(x), which are only conditionally defined
in sys/cdefs.h (conditional on __GNUC__ or __INTEL_COMPILER).

Bug in FreeBSD, but as work-around we can define __GNUC__ which
picks up these defs.

[This also moves back the glibc defines we had before into the
non-BSD ifdef branch]
2016-10-17 01:08:29 +02:00
Michael Matz
68a7af632c x86-64: Fix long long bug
With the last improvements to lexpand it's now harmful
to use on native 64bit platforms when not necessary.  For gv_dup
it's not necessary there.  It can still be used with really
transforming a 64bit value into two 32bit ones.
2016-10-17 00:57:16 +02:00
grischka
d9b7f018ce i386: do not 'lexpand' into registers necessarily
Previously, long longs were 'lexpand'ed into two registers
always.

Now, it expands
- constants into two constants (lo-part, hi-part)
- variables into two lvalues with offset+4 for the hi-part.

This makes long long operations look a bit nicer.

Also: don't apply i386 'inc/dec' optimization if carry
generation is wanted.
2016-10-16 19:04:40 +02:00
grischka
6245db9fca tccgen/32bits: fix unsigned long long -> int cast
gen_cast() failed to truncate long long's if they
were unsigned, which was causing mess on the vstack.

There was a similar bug here
    tccgen: 32bits: fix PTR +/- long long
    ed15cddacd

Both were not visible until this patch
    tccgen: arm/i386: save_reg_upstack
    b691585785

I'd still assume that this patch is correct per se.

Also:
- remove 2x !nocode_wanted (we are already under a general
  "else if (!nocode_wanted)" clause above).
2016-10-16 11:03:57 +02:00
Christian Jullien
4ac0e1971e Actual complete name for DragonFly is 'DragonFly BSD'. 2016-10-16 06:12:55 +02:00
Christian Jullien
06db384f8a No 'Thread Storage Local' on FreeBSD with tcc. 2016-10-15 18:47:31 +02:00
Christian Jullien
f7bfa0970e Backslash was missing after reindentation to let code be < 80 col. 2016-10-15 18:13:01 +02:00
grischka
f3c1ea6c2d #define __GNUC__ = 2.1
__GNUC__ nowadays as macro seems to mean the "GNU C dialect"
rather than the compiler itself.  See also

  http://gcc.gnu.org/ml/gcc/2008-07/msg00026.html

This patch will probably cause problems of various kinds but
maybe we should try nonetheless.
2016-10-15 16:01:16 +02:00
grischka
4d247c00a3 tccgen/tccelf: move code from libtcc.c 2016-10-15 15:55:31 +02:00
Christian Jullien
3e32479594 Add more OpenBSD support. 2016-10-15 15:08:44 +02:00
Christian Jullien
70dec93f2b OpenBSD does not support -v option in rm command. 2016-10-15 14:59:52 +02:00
Christian Jullien
36759ddacf Start support of OpenBSD, tcc compiler can be produced from source tree 2016-10-15 14:50:17 +02:00
Christian Jullien
18a5d8188a World is not reduced to either Windows or Linux 2016-10-15 09:47:08 +02:00
Michael Matz
383f568a64 Fix misleading indentation 2016-10-14 17:46:04 +02:00
Michael Matz
682ecc1745 arm64: Fix -run
With -run the call instruction and a defined function can be
far away, if the function is defined in the executable itself,
not in the to be compiled code.  So we always need PLT slots
for -run, not just for undefined symbols.
2016-10-14 17:32:10 +02:00
Michael Matz
7600b03f35 arm64: Support PREL32 relocation
A PC-relative 32bit value is stored.
2016-10-14 16:47:43 +02:00
Michael Matz
c232af7ddb Support archives with 64 bit indices
Some systems started using SYM64 .a libraries, so start
supporting them.
2016-10-14 16:47:43 +02:00
grischka
ed15cddacd tccgen: 32bits: fix PTR +/- long long
Previously in order to perform a ll+ll operation tcc
was trying to 'lexpand' PTR in gen_opl which did
not work well.  The case:


    int printf(const char *, ...);
    char t[] = "012345678";

    int main(void)
    {
        char *data = t;
        unsigned long long r = 4;
        unsigned a = 5;
        unsigned long long b = 12;

        *(unsigned*)(data + r) += a - b;

        printf("data %s\n", data);
        return 0;
    }
2016-10-13 19:21:43 +02:00
Christian Jullien
8986bc8af4 Use ISO C string functions instead of obsolete BSD ones that used to be in strings.h. It allows more systems -- i.e. Windows -- to use those tests 2016-10-12 06:18:38 +02:00
Edmund Grimley Evans
07ca2df588 Use R_AARCH64_MOVW_UABS_G* instead of R_AARCH64_CALL26.
This is a work-around for TCC's linker, on AArch64, not building a PLT
when TCC is invoked with "-run". Fixing the linker should be possible:
it works on arm and x86_64, apparently.
2016-10-11 18:56:10 +01:00
Pavlas, Zdenek
7bd30a488a gcase() clean up
remove tail recursion, simplify
2016-10-11 02:05:02 -07:00
Edmund Grimley Evans
7dddd65b46 In gen_vla_sp_restore, use X30 rather than get_reg. 2016-10-10 20:15:57 +01:00
Edmund Grimley Evans
94d8d12c26 Fix handling of case_reg in switch statement.
The back end functions gen_op(comparison) and gtst() might allocate
registers so case_reg should be left on the value stack while they
are called and set again afterwards.

This bug fix was first applied as ff3f9aa (20 Feb 2015), but the fix
was reverted by fc0fc6a (21 Sep 2016, "switch: collect case ranges
first, then generate code"). Here the fix is updated for the new code.
2016-10-10 20:15:20 +01:00
Avi Halachmi (:avih)
5a0ca53a4a build: strip: unify win32 and use the configured $STRIP
- There's no need to force STRIP_BINARIES on windows since --enable-strip (at
  configure) already does exactly that, if one wants to.
- Use the contigured $STRIP instead of the native 'strip', useful when
  cross building tcc.
- 'make install-strip' now also strips libtcc.dll on windows (it already does
  so now with --enable-strip, and previously it always stripped it).

Summary of current strip options for all platforms:
- configure --enable strip -> 'install -s' for the binaries.
- make install-strip: installs and then configured $STRIP the binaries.
- Otherwise -> no stripping.
2016-10-10 15:17:58 +03:00
Avi Halachmi (:avih)
35b7bf9382 build: win: detect also mingw64 in msys2 setup
MSYS2 installs 3 environments, with uname (e.g. on win8.1 64) as follows:
- MINGW32_NT-6.3  gcc -> stand-alone native i686 binaries
- MINGW64_NT-6.3  gcc -> stand-alone native x86_64 binaries
- MSYS_NT-6.3     gcc -> posix-ish binaries which can only run in this env

Therefore 'MINGW' is more generic and detects both 32/64 native
environments, where previously 'MINGW32' detected only the 32 one.
2016-10-10 14:55:34 +03:00
Avi Halachmi (:avih)
07818ec6a7 build: out-of-tree: fix docs 2016-10-10 14:54:04 +03:00
Avi Halachmi (:avih)
61894e17cd build: win32: don't use mklink - use ln or fallback to cp
For the following reasons:
- Native windows links are rarely used in general.
- Require elevated privileges even if the current user has administrator
  privileges (needs further "run as administrator").
- Most/all windows shell environments capable of running configure already
  support ln (msys[1], msys2, most probably cygwin too).
- If cross building tcc on linux for windows then native mklink is not
  available, as well as 'cmd' (in this scenario the build later fails
  for other reasons, but at least configures succeeds now).
- cp is good enough as fallback since we only copy 5 makefiles anyway.
- The only environment I'm aware of which doesn't support ln -s is busybox
  for windows, and with this patch it falls back to cp and completes
  configure successfully (and the build later succeeds, assuming valid
  $CC and $AR).
2016-10-10 14:50:48 +03:00
grischka
71b16f4e18 tccpp : "tcc -E -P" : suppress empty lines
Also:
- regenerate all tests/pp/*.expect with gcc
- test "insert one space" feature
- test "0x1E-1" in asm mode case
- PARSE_FLAG_SPACES: ignore \f\v\r better
- tcc.h: move some things
2016-10-09 20:33:14 +02:00
Daniel Glöckner
78c08898ae arm-gen.c: support VLAs 2016-10-09 00:14:40 +02:00
Daniel Glöckner
bf10bca192 tccgen.c: make vla_runtime_type_size always return the alignment 2016-10-09 00:13:31 +02:00
Daniel Glöckner
52a152235e arm-gen.c: replace register constants with enum values
and support sp in intr
2016-10-09 00:11:51 +02:00
Daniel Glöckner
6775c7cb3a tccgen.c: fix multi-register structure return when not on stack
We need to preserve the type of the pointer to the structure, f.ex.
when a global structure is returned.

This is not a perfect solution. Registers loaded in the first iteration
might be overwritten in a following iteration as the register is no
longer on vtop. This is not a problem for ARM32 as gfunc_sret returns
a maximum of 1 in the integer case.
2016-10-08 19:03:01 +02:00
Daniel Glöckner
c09b6ce975 tccgen.c: use correct type for storing long double constants 2016-10-08 18:52:28 +02:00
Daniel Glöckner
3dfee1d290 arm-gen.c: detect long double structures as HFA
when long double is equal to double
2016-10-08 18:47:35 +02:00
grischka
b42cb16b65 Misc. fixes
Makefile :
- do not 'uninstall' peoples /usr/local/doc entirely
libtcc.c :
- MEM_DEBUG : IDE-friendly output "file:line: ..."
- always ELF for objects
tccgen.c :
- fix memory leak in new switch code
- move static 'in_sizeof' out of function
profiling :
- define 'static' to empty
resolve_sym() :
- replace by dlsym()

win32/64: fix R_XXX_RELATIVE fixme
- was fixed for i386 already in
  8e4d64be2f
- do not -Lsystemdir if compiling to .o
2016-10-05 18:34:17 +02:00
grischka
b691585785 tccgen: arm/i386: save_reg_upstack
tccgen.c:gv() when loading long long from lvalue, before
was saving all registers which caused problems in the arm
function call register parameter preparation, as with

    void foo(long long y, int x);
    int main(void)
    {
      unsigned int *xx[1], x;
      unsigned long long *yy[1], y;
      foo(**yy, **xx);
      return 0;
    }

Now only the modified register is saved if necessary,
as in this case where it is used to store the result
of the post-inc:

        long long *p, v, **pp;
        v = 1;
        p = &v;
        p[0]++;
        printf("another long long spill test : %lld\n", *p);

i386-gen.c :
- found a similar problem with TOK_UMULL caused by the
  vstack juggle in tccgen:gen_opl()
  (bug seen only when using EBX as 4th register)
2016-10-04 17:36:51 +02:00
grischka
1c4cf18556 tccpp: no cache for include if #elif seen
#ifndef guards are cached, however after #elif on the
same level, the file must be re-read.

Also: preprocess asm as such even when there is no
assembler (arm).
2016-10-04 17:31:40 +02:00
grischka
5805b07218 Alternative fix for "Incorrect function call code on ARMv6"
"make test" crashes without that "save_regs()".

This partially reverts
commit 49d3118621.

Found another solution:  In a 2nd pass Just look if
any of the argument registers has been saved again,
and restore if so.
2016-10-03 12:33:41 +02:00
grischka
78f1c10e0f configure: fix tcc_lddir, cpu
... and other minor cosmetic fixes
2016-10-03 12:33:40 +02:00
Pavlas, Zdenek
f795e1be83 switch: binary search 2016-10-03 03:14:34 -07:00
Pavlas, Zdenek
da63695cf3 switch: fix label sorting 2016-10-03 00:43:28 -07:00
grischka
c2ad11ac70 tccgen: fix long long -> char/short cast
This was causing assembler bugs in a tcc compiled by itself
at i386-asm.c:352 when ExprValue.v was changed to uint64_t:

    if (op->e.v == (int8_t)op->e.v)
        op->type |= OP_IM8S;

A general test case:

    #include <stdio.h>
    int main(int argc, char **argv)
    {
        long long ll = 4000;
        int i = (char)ll;
        printf("%d\n", i);
        return 0;
    }

Output was "4000", now "-96".

Also: add "asmtest2" as asmtest with tcc compiled by itself
2016-10-02 01:39:14 +02:00
grischka
f350487e1e win32/64: msys2 support
Support ./configure && make under msys2 (a new msys fork)
on win32 and win64.

Get rid of CONFIG_WIN64 make-var. (On windows, WIN32 in
general is used for both 32 and 64 bit platforms)

Also:
- cleanup win32/build-tcc.bat
- adjust win32/(doc/)tcc-win32.tx
2016-10-02 01:39:07 +02:00
Balazs Kezes
49d3118621 Incorrect function call code on ARMv6
On 2016-08-11 09:24 +0100, Balazs Kezes wrote:
> I think it's just that that copy_params() never restores the spilled
> registers. Maybe it needs some extra code at the end to see if any
> parameters have been spilled to stack and then restore them?

I've spent some time on this and I've found an alternative solution.
Although I'm not entirely sure about it but I've attached a patch
nevertheless.

And while poking at that I've found another problem affecting the
unsigned long long division on arm and I've attached a patch for that
too.

More details in the patches themselves. Please review and consider them
for merging! Thank you!

--
Balazs

[PATCH 1/2] Fix slow unsigned long long division on ARM

The macro AEABI_UXDIVMOD expands to this bit:

  #define AEABI_UXDIVMOD(name,type, rettype, typemacro)                     \
  ...
      while (num >= den) {                                                  \
  ...
          while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \
              q <<= 1;                                                      \
  ...

With the current ULONG_MAX version the inner loop goes only until 4
billion so the outer loop will progress very slowly if num is large.
With ULLONG_MAX the inner loop works as expected. The current version is
probably a result of a typo.

The following bash snippet demonstrates the bug:

  $ uname -a
  Linux eper 4.4.16-2-ARCH #1 Wed Aug 10 20:03:13 MDT 2016 armv6l GNU/Linux
  $ cat div.c
  int printf(const char *, ...);
  int main(void) {
    unsigned long long num, denom;
    num = 12345678901234567ULL;
    denom = 7;
    printf("%lld\n", num / denom);
    return 0;
  }
  $ time tcc -run div.c
  1763668414462081

  real    0m16.291s
  user    0m15.860s
  sys     0m0.020s

[PATCH 2/2] Fix long long dereference during argument passing on ARMv6

For some reason the code spills the register to the stack. copy_params
in arm-gen.c doesn't expect this so bad code is generated. It's not
entirely clear why the saving part is necessary. It was added in commit
59c35638 with the comment "fixed long long code gen bug" with no further
clarification. Given that tcctest.c passes without this, maybe it's no
longer needed? Let's remove it.

Also add a new testcase just for this. After I've managed to make the
tests compile on a raspberry pi, I get the following diff without this
patch:

  --- test.ref    2016-08-22 22:12:43.380000000 +0100
  +++ test.out3   2016-08-22 22:12:49.990000000 +0100
  @@ -499,7 +499,7 @@
   2
   1 0 1 0
   4886718345
  -shift: 9 9 9312
  +shift: 291 291 291
   shiftc: 36 36 2328
   shiftc: 0 0 9998683865088
   manyarg_test:

More discussion on this thread:
https://lists.nongnu.org/archive/html/tinycc-devel/2016-08/msg00004.html
2016-10-01 23:10:11 +02:00
orbea
d25948c5a7 Fix building man pages.
The path for texi2pod.pl in the makefile was wrong
causing the perl script to not be found.
2016-10-01 13:25:46 -07:00
grischka
e03306d170 tccelf: allow multiple declaration of bss/common symbols
also in combination with one initialized:

For example
  1.c
     int xxx;
  2.c
     int xxx = 2;
  3.c
     int xxx;

tcc 1.c 2.c 3.c
2016-10-01 22:01:33 +02:00
grischka
332cf5327f tccpp: parse_line_comment: fix possible buffer overrun 2016-10-01 22:01:25 +02:00
grischka
5a23a72aed tccpp: allow "0x1e+1" in asm 2016-10-01 21:58:02 +02:00
grischka
8afb8ccba2 tccpp: token ## pasting: preserve parts if pasting fails
for example
    #define LBL(name) _ ## name ## :
    LBL(main)
will give two tokens
    '_main' and ':'
and the warning
2016-10-01 21:57:40 +02:00
grischka
c5b9ae4e3f Revert "-fnormalize-inc-dirs"
Too much code. gcc 3.x doesn't have that either.

This reverts commit 41785a0bf9.
This reverts commit 21665f4338.
2016-10-01 21:57:22 +02:00
grischka
643a1b8848 tcc -E: add one space in cases: tiny solution
replaces f5f82abc99

Also: fix tcc flags in Makefile, fix tcc -E
2016-10-01 21:52:11 +02:00
grischka
afdbc5b815 build: restore out-of-tree support 2016-10-01 21:06:53 +02:00
grischka
0a624782df build: revert Makefiles to 0.9.26 state (mostly)
Except
- that libtcc1.a is now installed in subdirs i386/ etc.
- the support for arm and arm64
- some of the "Darwin" fixes
- tests are mosly unchanged

Also
- removed the "legacy links for cross compilers" (was total mess)
- removed "out-of-tree" build support (was broken anyway)
2016-10-01 21:06:33 +02:00
grischka
6d2be31b93 test/pp: cleanup 2016-10-01 21:05:42 +02:00
grischka
0d9f88ea67 libtcc: reimplement option -Wl,[-no]-whöle-archive
- taking advantage of previous commit "incremental -Wl parsing"
2016-10-01 20:54:45 +02:00
grischka
2f1174550e libtcc: -Wl,... incremental parsing
parse -Wl linker options immediately
2016-10-01 20:49:38 +02:00
grischka
2d6aa65067 Revert "output all sections if we produce an executable file"
-- Not a fix
This reverts commit 089ce6235c.

Revert "handle a -s option by executing sstrip/strip program"
-- related, not a fix.
This reverts commit 5cd4393a54.
2016-10-01 20:48:01 +02:00
grischka
9c5bb16447 Revert part of "fix installation amd bcheck for Windows"
tccelf.c : force linking bcheck by adding elf symbol __bound_init
bcheck.c : use (size_t)1 for x86_64

Fixes 7e7e6148fd
2016-10-01 20:47:36 +02:00
grischka
acac35c125 libtcc: filetype cleanup
- does not change signature of tcc_add_file
2016-10-01 20:46:16 +02:00
grischka
8637c1d0ad Remove misc. files
- from win32/include/winapi: various .h

  The winapi header set cannot be complete no matter what.  So
  lets have just the minimal set necessary to compile the examples.

- remove CMake support (hard to keep up to date)
- some other files

Also, drop useless changes in win32/lib/(win)crt1.c
2016-10-01 20:27:41 +02:00
grischka
766ba3694d tccpp: cleanup
- "utf8 in identifiers"
  from 936819a1b9

- CValue: remove member str.data_allocated
- make tiny allocator private to tccpp

- allocate macro_stack objects on heap
  because otherwise it could crash after error/setjmp
  in preprocess_delete():end_macro()

- mov "TinyAlloc" defs to tccpp.c

- define_push: take int* str again
2016-10-01 20:26:50 +02:00
grischka
eacdc426d7 libtcc: cleanup @listfile
Also:
- allow more than one item per line
- respect "quoted items" and escaped quotes \"
  (also for LIBTCCAPI tcc_setoptions)

- cleanup some copy & paste
2016-10-01 20:19:37 +02:00
grischka
09a487eb2b libtcc: cleanup -x<filetype> switch code
Abusing filename[0] as type is just too much of a hack.
-- From 0536407204
2016-10-01 20:04:58 +02:00
grischka
e630113771 Revert "ability to compile multiple *.c files with -c switch"
copy & paste coding, twisted control flow
This reverts commit a13f183e4c.

Also, set linker args for DLLs also.
2016-10-01 20:04:33 +02:00
grischka
3ddbfe1a82 tccpp: #pragma once: make it work
after several "fixes" and "improvements"
   b3782c3cf5
   5fb57bead4
feature did not work at all

- Use 'once' flag, not 'ifndef_macro'
- Ignore filename letter case on _WIN32
- Increment global pp_once for each compilation
2016-10-01 20:03:48 +02:00
grischka
07e47b3dd6 tccpp: restore -D symbols for multiple sources
... also for built-in defines

The case:
    $ tcc -D FOO a.c b.c
with
    // a.c
    #undef FOO

    // b.c
    #ifndef FOO
    # error -D FOO has been lost
    #endif
2016-10-01 19:58:13 +02:00
grischka
cf32bb8812 Revert "--whole-archive support"
- would parse linker args in two different places
- would mess up "tcc -v ..." output:
  	tcc -v test.c
  	-> test.c
  	+> test.c
- would use function "tcc_load_alacarte()" to do the contrary of
  what its name suggests.

This reverts commit 19a169ceb8.
2016-10-01 19:56:25 +02:00
Pavlas, Zdenek
e238e6521b gtst_addr(): short conditional jumps (i386, x86_64) 2016-09-30 07:33:20 -07:00
Pavlas, Zdenek
fc0fc6aba3 switch: collect case ranges first, then generate code
Collect cases first, then emit lookup code. Elliminates
jumps to implement pass-through and jumps to link cases.
2016-09-30 07:33:20 -07:00
Jean-Claude Beaudoin
d5a1e32ac3 Prevent tail spin crash when option -pthread is used. 2016-09-29 16:23:11 -04:00
Jean-Claude Beaudoin
beab3f8c71 Use etags to produce target TAGS. 2016-09-29 16:18:23 -04:00
Jean-Claude Beaudoin
889ee28ed5 Rein in unintended external functions on Windows. 2016-09-27 01:43:40 -04:00
Jean-Claude Beaudoin
08335c1548 More properly propagate ONE_SOURCE. 2016-09-27 01:40:49 -04:00
Christian Jullien
e037fd3364 pstrcpy looks to be needed by Windows win32/win64 builds. Reverted as PUB_FUNC to allow tcc.exe build again. 2016-09-26 07:02:42 +02:00
Christian Jullien
6db7a2157b Merge branch 'mob' of git://repo.or.cz/tinycc into mypatch
Add Visual Studio processor identification
2016-09-26 06:42:43 +02:00
Christian Jullien
30238b1ebd Add Microsoft processor identification 2016-09-26 06:41:31 +02:00
Jean-Claude Beaudoin
ff158bffe6 Rein in unintended external functions. 2016-09-25 22:32:41 -04:00
Christian Jullien
e38f49e32a Fix test for __*LP*__ predefined macros 2016-09-25 12:13:17 +02:00
Christian Jullien
c1b101cbaf Improve __*LP*__ predefined macros 2016-09-25 12:03:23 +02:00
Christian Jullien
e91ce66dad Add test for __*LP*__ predefined macros 2016-09-25 12:01:10 +02:00
Pavlas, Zdenek
c948732efa x86_64/elf: only variadic calls need rax 2016-08-17 06:23:15 -07:00
David Mertens
0373fe0e2a Remove vestiges of earlier type merger 2016-08-16 15:25:09 -04:00
Pavlas, Zdenek
71b6220963 tccgen: return: avoid jmp to retsym if possible
When 'return' is the last statement of the top-level block
(very common and often recommended case) jump is not needed.
2016-08-11 05:02:40 -07:00
David Mertens
0a402f6e91 Avoid conflicting definition for va_list on 64-bit Macs 2016-08-04 13:14:52 -04:00
grischka
41349948f8 win64: fix va_arg
fixes 5c35ba66c5

Implementation was consistent within tcc but incompatible
with the ABI (for example library functions vprintf etc)

Also:
- tccpp.c/get_tok_str() : avoid "unknown format "%llu" warning
- x86_64_gen.c/gen_vla_alloc() : fix vstack leak
2016-07-10 20:44:49 +02:00
Vincent Lefevre
0360905124 fix typo in -Wl,-rpath documentation
Signed-off-by: Vincent Lefevre <vincent@vinc17.net>
2016-07-05 15:48:31 +02:00
Avi Halachmi (:avih)
1751588435 tiny_libmaker: fix a comment 2016-06-19 22:19:06 +03:00
Avi Halachmi (:avih)
3f21d81073 win32: _mingw.h: add definition for _TRUNCATE from newer _mingw.h 2016-06-19 14:44:31 +03:00
Avi Halachmi (:avih)
ab8422c8e7 win32: malloc.h: use alloca instead of (missing) _alloca
_alloca is not part of msvcrt (and therefore not found if used), and tcc has
an internal implementation for alloca for x86[_64] since d778bde7 - initally
as _alloca and later changed to alloca. Use it instead.
2016-06-19 14:44:18 +03:00
Avi Halachmi (:avih)
b67951bed4 win32: wchar.h: don't redifine WCHAR_MIN[/MAX] (after stdint.h) 2016-06-19 14:44:07 +03:00
Avi Halachmi (:avih)
100f94be99 tiny_libmaker: more robust arguments interpretation
- Syntax is now much closer to gnu ar, but still supports whatever was
  supported before, with the following exceptions (which gnu ar has too):
  - lib is now mandatory (was optional and defaulted to ar_test.a before).
  - Path cannot start with '-' (but ./-myfile.o is OK).
- Unlike gnu ar, modes are still optional (as before).
- Now supports also (like gnu ar):
  - First argument as options doesn't have to start with '-', later options do.
  - Now supports mode v (verbose) with same output format as gnu ar.
  - Any names for lib/objs (were limited to .a/.o - broke cmake on windows).
  - Now explicitly fail on options which would be destructive for the user.
  - Now doesn't get confused by options between file arguments.
- Still ignores other unknown options - as before.
- Now doesn't read out-of-bounds if an option is one char.

- As a result, cmake for windows can now use tiny_libmaker as ar, and
  configure can also detect tiny_libmaker as a valid ar (both couldn't before).

Ignoring all options could previously cause to misinterpret the mode in a
destructive way, e.g. if the user wanted to do something with an existing
archive (such as p - print, or x - extract, etc), then it would instead just
delete (re-create) the archive.

Modes which can be destructive if ignored now explicitly fail. These include
[habdioptxN]. Note that 'h' can be ignored, but this way we also implicitly
print the usage for -h/--help.

The .a/.o name limitations previously resulted in complete failure on some
cases, such as cmake on windows which uses <filename>.obj and <libname>.lib .

Fixed: e.g. 'tiny_libmaker r x.a x.o' was reading out of bounds [-1] for 'r'.
2016-06-19 14:43:46 +03:00
grischka
1ca685f887 tccgen: gen_assign_cast(): cannot cast struct to scalar
The case below previously was causing an assertion failure
in the target specific generator.

It probably is not incorrect not to allow this even if
gcc does.

    struct S { long b; };

    void f(struct S *x)
    {
        struct S y[1] = { *x };
    }
2016-05-25 18:52:08 +02:00
grischka
9e0e05eb4e Redo "fix line number in macro redefined message"
Smaller change to fix more cases

This reverts commit 0f36f60faa.
2016-05-25 18:51:36 +02:00
seyko
bab4519617 Allow to perform tests from the custom build dir:
mkdir build; cd build
    ../configure --prefix=./package
    make
    make test
    make install
2016-05-20 16:02:42 +03:00
seyko
d0e48c51c7 [avih] a custom build dir fix for lib/Makefile
mkdir build; cd build
    ../configure && make
    ../../lib/libtcc1.c:31: error: include file 'stddef.h' not found

    Author: Avi Halachmi
    Date:   Sat Nov 14 18:40:36 2015 +0200
    When building from the root tcc dir, $TOP and $top_srcdir
    are the same, but with a custom build dir, we need top_srcdir
2016-05-20 15:55:36 +03:00
seyko
18cbe62e69 fix a mingw64 build on Linux with --enable-tcc64-mingw
* define CONFIG_WIN64=yes when ARCH=x86-64 (not CONFIG_WIN32=yes)
    * CONFIG_WIN64 now use a windows install part (not a Linux one)
2016-05-20 15:48:02 +03:00
seyko
824b1b582f make and install tiny_libmaker on all platforms
not only on Windows/Darwin.
2016-05-20 15:33:53 +03:00
seyko
778ec44adc [avih] configure: support custom ar with --ar=
Author: Avi Halachmi (:avih)
    Date:   Mon Nov 2 18:46:32 2015 +0200

    configure: support custom ar with --ar=
2016-05-20 15:27:22 +03:00
seyko
4e7a8906a1 configure: docdir fix
was /usr/local/share/doc/usr/local/lib/tcc
    now /usr/local/share/doc
2016-05-20 15:21:26 +03:00
seyko
19a169ceb8 --whole-archive support
A patch is implemented as suggested in tinycc-devel mail list.

    From: Reuben Thomas
    Date: Thu, 31 Jul 2014 16:52:53 +0100
    Subject: [PATCH] Add --{no,}-whole-archive support

    I resurrected the patch supplied to the mailing list in 2009
    Since --whole-archive is a useful flag to get tcc working with
    autotools, and of course in its own right, I suggest you have a look
    at the patch and see if it is acceptable. I cannot see any suggestion
    that it was actively rejected last time round, just no evidence that
    it was ever added.
2016-05-20 15:12:32 +03:00
Christian Jullien
1339d04759 Microsoft says that _spawnp must be used instead of spawnp. It fixes a warning when compiled with MinGW 32/64 gcc compilers 2016-05-16 17:58:56 +02:00
seyko
3f233ab127 fix asm_expr_unary()
keep unary unsigned.
    problem is exposed on i386 with unary like 0xC0000000.
    In this case a sign is extended in
        pe->v = n;
    if n declared as long.
2016-05-16 08:53:24 +03:00
Michael Matz
f2a4cb0a0e x86-asm: Reject some invalid arith imm8 instruction
There were two errors in the arithmetic imm8 instruction.  They accept
only REGW, and in case the user write a xxxb opcode that variant
needs to be rejected as well (it's not automatically rejected by REGW
in case the destination is memory).
2016-05-16 05:10:21 +02:00
seyko
0f36f60faa fix line number in macro redefined message 2016-05-16 03:21:26 +03:00
seyko
a37f8cfc80 short_call_convention patch from tcc bugzilla
BUGZILLA:
    interfacing with other compilers

    extend the return value to the whole register if necessary.
    visual studio and gcc do not always set the whole eax register
    when assigning the return value of a function.

    We've encountered wrong execution results on i386 platforms with an
    application that uses both code compiled with TCC and code compiled
    with other compilers (namely: Visual Studio on Windows, and GCC on
    Linux).

    When calling a function that returns an integer value shorter than 32
    bits, TCC reads the return value from the whole EAX register,
    although the code generated by the other compilers can only sets AL
    for 8 bit values or AX for 16 bits values, and the rest of EAX can be
    anything.

    We worked around this with the attached patch on i386 for the version
    0.9.26, but we did not look at other platforms to find if there are
    similar issues.
2016-05-15 21:10:06 +03:00
seyko
9d679e3916 memory model macros __{L,}LP64__
a patch from tcc bugzilla.
    From: Reuben Thomas
    Date: Thu, 31 Jul 2014 13:50:13 +0100
    Subject: [PATCH] libtcc.c: add memory model macros __{L,}LP64__
2016-05-15 21:07:05 +03:00
Michael Matz
7cfd21440b x86-asm: Add .fill test 2016-05-14 04:41:06 +02:00
Michael Matz
4f27e217a8 x86-asm: Fix signed constants and opcode order
Two things: negative constants were rejected (e.g. "add $-15,%eax").
Second the insn order was such that the arithmetic IM8S forms
weren't used (always the IM32 ones).  Switching them prefers those
but requires a fix for size calculation in case the opcodes were
OPC_ARITH and OPC_WLX (whose size starts with 1, not zero).
2016-05-14 04:33:41 +02:00
Michael Matz
080ec9fadd x86-asm: Consolidate insn descriptions
Use OPC_BWLX and OPC_WLX in i386-asm.h and x86_64-asm.h to
reduce number of differences between both.
2016-05-14 04:05:34 +02:00
grischka
5e4d0718ff tcc -E -P10 : output all numbers as decimals
This may be used to preprocess Fabrice Bellards initial revision
in this repository to demonstrate its capability to compile and
run itself (on i386 32-bit linux or windows).

Initial revision: 27f6e16bae

Also needed:
* an empty stdio.h
* a wrapper named tc.c with

  void expr(void);
  void decl(int);
  void next(void);
  #include "tcc.c"

* an hello.c such as

  int main()
  {
      printf("Hello World\n");
      return 0;
  }

All files with unix LF only lines.  Then ...

* preprocess the source
  $ tcc -E -P10 -I. tcc.c -o tc1.c
* compile the compiler
  $ tcc -w -I. tc.c -o tc -ldl
* run it to compile and
   run itself to compile and
    run itself to compile and
     run itself to compile and
      run hello.c
$ ./tc tc1.c tc1.c tc1.c hello.c

--> Hello World!

------------------------------------------------------
* On i386 windows this may be added to the tc.c wrapper

  #ifdef _WIN32
  #include <windows.h>
  void *dlsym(int x, const char *func)
  {
      if (0 == strcmp(func, "dlsym"))
          return &dlsym;
      return GetProcAddress(LoadLibrary("msvcrt"), func);
  }
  #endif
2016-05-12 10:25:50 +02:00
Michael Matz
a66ba1f2a1 Error out on operations on structs
The check for structs was too late and on amd64 and aarch64 could
lead to accepting and then asserting with code like:
  struct S {...} s;
  char *c = (char*)0x10 - s;
2016-05-12 01:12:04 +02:00
Michael Matz
6bd8c936e3 x86-64-asm: Add mov[sz]xq opcodes
This adds the zero/sign-extending opcodes with 64bit destinations.
2016-05-12 00:57:02 +02:00
Michael Matz
b9f01dffc6 x86-64-asm: Clean up 64bit immediate support
Fix it to actually be able to parse 64bit immediates (enlarge
operand value type).  Then, generally there's no need for accepting
IM64 anywhere, except in the 0xba+r mov opcodes, so OP_IM is
unnecessary, as is OPT_IMNO64.  Improve the generated code a bit
by preferring the 0xc7 opcode for im32->reg64, instead of the
im64->reg64 form (which we therefore hardcode).
2016-05-11 23:47:02 +02:00
Michael Matz
f3cee9ceff x86-asm: Get rid of is_short_jump
Can be implemented differently.
2016-05-11 23:45:14 +02:00
Michael Matz
55bd08c5ae x86-asm: Remove old ASM_16 code
This code was inactive since a long time (and was deactivated because
it was wrong to start with) and just clutters the sources.  Remove
it.
2016-05-11 19:13:38 +02:00
Michael Matz
f0fa5603cf x86-64: Run asmtest as well
This fixes and activates the asm test that's part of tcctest.c
also on x86-64, requiring a small fix for the 'm' constraint.
2016-05-11 19:00:02 +02:00
Michael Matz
4d68828259 tests: Compile asmtest.S without -m32
Don't hardcode that option, if you want it do make CC="gcc -m32".
The test assembles with -m64 as well now.
2016-05-11 18:58:14 +02:00
Michael Matz
613962e353 x86-64 asm: Remove useless jmp opcode
Also remove the hacky mod/rm byte emission during
disp/imm writing.
2016-05-11 18:56:19 +02:00
Michael Matz
bd93dc6923 x86: Improve cmov handling
cmov can accept multi sizes, but is also a OPC_TEST opcode,
deal with this.
2016-05-11 18:54:24 +02:00
Michael Matz
9645b62a65 x86_64: Use addend on relocs
Traditional behaviour on x86-64 is to encode the relocation
addend in r_addend, not in the relocated field (after all,
that's the reason to use RELA relocs to begin with).  Our
linker can deal with both, other linkers as well.  But using
e.g. the GNU assembler one can detect differences (equivalent
code in the end, but still a difference).

Now there's only a trivial difference in tests/asmtest.S
(having to do with ordering of prefixes).
2016-05-09 23:17:47 +02:00
Michael Matz
5e47b08dc8 [x86] Fix some asm problems
A bag of assembler fixes, to be either compatible with GAS
(e.g. order of 'test' operands), accept more instructions,
count correct foo{bwlq} variants on x86_64, fix modrm/sib bytes
on x86_64 to not use %rip relative addressing mode, to not use
invalid insns in tests/asmtest.S for x86_64.

Result is that now output of GAS and of tcc on tests/asmtest.S
is mostly the same.
2016-05-09 23:17:47 +02:00
Edmund Grimley Evans
f5f82abc99 Insert spaces between certain tokens when tcc is invoked with -E.
Insert a space when it is required to prevent mistokenisation of
the output, and also in a few cases where it is not strictly
required, imitating GCC's behaviour.
2016-05-09 19:27:31 +01:00
seyko
75243f744c TOK_PPNUM in asm (Edmund Grimley Evans version) 2016-05-08 05:14:03 +03:00
grischka
a94e8d439a tccgen: scopes levels for local symbols (update 2)
allow
    typedef int xxx;
    typedef int xxx;
in the same scope as long as it is the same type
2016-05-06 08:32:54 +02:00
grischka
d48662d496 tccgen: scopes levels for local symbols (update 1)
Catch top level redeclarations too.

Also fix mistakes in tcctest.c and the tcc sources (win32)
showing up now.
2016-05-05 20:04:00 +02:00
grischka
fe845cf53d tccpp: cleanup options -dD -dM, remove -C
The lexer is for reading files, not for writing.

Also :
- macro_is_equal(): avoid crash if redefining __FILE__
2016-05-05 14:12:53 +02:00
grischka
caebbc3ee1 tccgen: scope levels for local symbols
... for fast redeclaration checks

Also, check function parameters too:
    void foo(int a) { int a; ... }

Also, try to fix struct/union/enum's on different scopes:
    { struct xxx { int x; };
         { struct xxx { int y; }; ... }}
and some (probably not all) combination with incomplete
declarations "struct xxx;"

Replaces 2bfedb1867
and 07d896c8e5

Fixes cf95ac399c
2016-05-05 10:39:09 +02:00
Edmund Grimley Evans
0fbc77cac6 tests/tests2/Makefile: Make 85-asm-outside-function Intel-only. 2016-05-04 21:23:25 +01:00
Edmund Grimley Evans
a348513569 Revert 78e4ee5. 2016-05-04 20:27:39 +01:00
Edmund Grimley Evans
6015840583 Revert 3283c26 and a1c1390 in tccpp.c. 2016-05-04 20:14:39 +01:00
seyko
07d896c8e5 sym_push2 optimized for the local_stack case.
A constant expression removed from the loop.
    If subroutine have 50000+ local variables, then currently
    compilation of such code takes obly 15 sec. Was 2 min.
    gcc-4.1.2 compiles such code in 7 sec. pcc -- 3.44 min.

    A test generator:
    #include <stdio.h>
    int main() {
        puts("#include <stdio.h>"); puts("int main()"); puts("{");
        for (int i = 0; i < 50000; ++i) printf("int X%d = 1;\n", i);
        for (int i = 0; i < 50000; ++i) puts("scanf(\"%d\", &X0);");
        puts("}");
        return 0;
    }
2016-05-04 17:23:25 +03:00
seyko
2bfedb1867 -fno-type-redefinition-check
don't catch redefinition for local vars. With this option on
    tcc accepts the following code:
    int main()
    {
        int a = 0;
        long a = 0;
    }
    But if you shure there is no problem with your local variables,
    then a compilation speed can be improved if you have a lots of
    the local variables (50000+)
2016-05-04 17:17:51 +03:00
seyko
78e4ee55b7 PP_NUM in ASM mode
oxe+1 is parsed as 0xe +1 if (parse_flags & PARSE_FLAG_ASM_FILE)
        Helps to compile a code:
        __asm__("mov $0xe" "+1", "%eax\n")
2016-05-04 16:54:40 +03:00
Michael Matz
78ee3759b8 x86-asm: Fix lcall/ljmp, xchg and inc/dec
Various x86 asm fixes: 64bit lcall/ljmp like 32bit a commit before,
xchgw accepted wrong operands on 32 and 64bit, and 64bit used
0x40/0x48+reg for incw/decw, but those are REX prefixes, not
instructions.
2016-05-03 01:16:43 +02:00
Michael Matz
d1515a0536 i386-asm: correct lcall/ljmp encoding
The 0xff/3 form of lcall needs a mod/rm byte, so reflect this.
2016-05-02 04:50:12 +02:00
seyko
6afe668ec7 __asm__() outside function
gcc/pcc allow __asm__() outside a function body:
    extern void vide(void);
    __asm__("vide: ret");

    There is many such code in the Linux kernels.
2016-05-01 22:38:38 +03:00
seyko
09a78412f0 lcall hex code correction 2016-05-01 22:14:00 +03:00
seyko
3283c26827 clearing "output space after TOK_PPNUM ..." 2016-05-01 16:36:19 +03:00
seyko
a1c139063b output space after TOK_PPNUM which followed by '+' or '-'
* correct -E output for the case ++ + ++ concatenation
        do this only for expanded from macro string
        and only when tcc_state->output_type == TCC_OUTPUT_PREPROCESS
2016-05-01 05:43:57 +03:00
grischka
256078933c tccpp: macro subst fix
#define Y(x) Z(x)
#define X Y
return X(X(1));

was : return Z(Y(1));
now : return Z(Z(1));
2016-04-29 19:00:33 +02:00
Edmund Grimley Evans
68ce8639bb TODO: Add two issues. 2016-04-24 22:44:57 +01:00
seyko
b4125ba0c1 fix for the "Reduce allocations overhead"
Now no trap when compiling tccboot
2016-04-22 20:32:15 +03:00
seyko
1f49441a27 .rept asm directive
and '.' alone is a token now in *.S (not an identifier)
    representing a current position in the code (PC).
2016-04-22 18:29:56 +03:00
seyko
edcb15c31f section alignment
Alignment of unknown sections changed from 32 to PTR_SIZE
    This is gcc/pcc default value. This helps to use
    tcc as linux kernel compiler.
2016-04-22 18:25:40 +03:00
seyko
8db7a0f7af Source and destination overlap in memcpy, cstr_cat (tccpp.c:322)
This code is from "Improve hash performance"
2016-04-22 18:21:09 +03:00
Michael Matz
d25f67ec12 Run testcases in sorted order
Without sorting they run in whatever order readdir returns,
I like it better when the order is reliable (and alphanumeric).
2016-04-22 15:57:23 +02:00
Vlad Vissoultchev
cdc16d428f Reduce allocations overhead
- uses new `TinyAlloc`-ators for small `TokenSym`, `CString` and
  `TokenString` instances
- conditional `TAL_DEBUG` for mem leaks and double frees detection
- on `TAL_DEBUG` collects allocation origin (file + line)
- conditional `TAL_INFO` for allocators stats (in release mode too)
- chain a new allocator twice current capacity on buffer exhaustion
2016-04-17 17:26:10 +03:00
Vlad Vissoultchev
224236f57c Improve hash performance
- better `TOK_HASH_FUNC`
- increases `hash_ident` initial size to 16k (from 8k)
- `cstr_cat` uses single `realloc` + `memcpy`
- `cstr_cat` can append terminating zero
- `tok_str_realloc` initial size to 16 (from 8)
- `parse_define` uses static `tokstr_buf`
- `next` uses static `tokstr_buf`
- fixes two latent bugs (wrong deallocations in libtcc.c:482 and
  tccpp.c:2987)
2016-04-17 17:25:55 +03:00
Vlad Vissoultchev
acc8f602e5 Revert "Fix tests Makefiles on Windows"
This reverts commit fa2472c172.
2016-04-17 17:24:17 +03:00
Vlad Vissoultchev
f021a7cd94 Add travis tests integration 2016-04-17 17:24:07 +03:00
seyko
587aacedf3 simplify -C printing
parse_print_line_comment() and parse_print_comment() are
    combined and made more simply:
        * don't worry about speed with -E option
        * don't handle straya in comments
            Do we need to handle strays in regular
            parse_line_comment() and
            parse_comment() ?
2016-04-17 10:07:55 +03:00
seyko
e010b1396b __builtin_expect no-op
Taken from David Mertens tcc branch on github
    https://github.com/run4flat/tinycc.git
2016-04-16 12:41:53 +03:00
seyko
5ee097fce9 allow to compile tcc by pcc
* pcc have only __linux__ macro (and no __linux)
    * pcc don't have __clear_cache proc
2016-04-15 17:41:49 +03:00
seyko
c6dc756d4e preprocessor oprtion -C (keep comments)
This is done by impression of the pcc -C option.
    Usual execution path and speed are not changed.
2016-04-15 17:15:11 +03:00
seyko
16cbca281f fix preprocessing *.S with ` ' chars in #comments
with a test program. Problem detected when trying to
    compile linux-2.4.37.9 with tcc.
2016-04-14 21:46:46 +03:00
seyko
5fb57bead4 fix for thev "#pragna once" guard
gcc 3.4.6 don't understand "#if PATHCMP==stricmp"
    where "#define PATHCMP stricmp"
2016-04-14 21:39:34 +03:00
Vlad Vissoultchev
34feee0ed6 Move utility functions trimfront/back to tccpp.c
These are used in `libtcc.c` now and cannot remain in `tccpe.c`
2016-04-13 14:33:21 +03:00
Vlad Vissoultchev
cb5f6b063b Simplify @listfiles parsing
This moves listfiles parsing inline in `tcc_parse_args1`
2016-04-13 11:35:24 +03:00
Vlad Vissoultchev
b3782c3cf5 Better pragma once guard
This takes care of case-insensitive filenames (like on win32)
2016-04-13 11:18:40 +03:00
Vlad Vissoultchev
98ffeaa0c5 win32: Better VS2015 solution and project files
These include all header and source files from source directory
2016-04-13 11:10:13 +03:00
Vlad Vissoultchev
810a677d32 tccpp.c: Guard against ppfp being NULL
Missed these in e946eb2a41
2016-04-13 10:58:42 +03:00
seyko
6a49afb3ed correct version of "Identifiers can start and/or contain"
A problem was in TOK_ASMDIR_text:
    -    sprintf(sname, ".%s", get_tok_str(tok1, NULL));
    +    sprintf(sname, "%s", get_tok_str(tok1, NULL));
    When tok1 is '.text', then sname is '..text'
2016-04-13 10:23:46 +03:00
seyko
989b5ee8ae Allow tcc arguments to be read from @listfiles
From: Vlad Vissoultchev
    Date: Tue, 12 Apr 2016 20:43:15 +0300
    Subject: Allow tcc arguments to be read from @listfiles

    This allows all @ prefixed arguments to be treated as listfiles
    containing list of source files or tcc options where each one is on a
    separate line. Can be used to benchmark compilation speed with
    non-trivial amount of source files.

    The impl of `tcc_parse_args` had to be moved to a new function that is
    able to be called recursively w/ the original one remaining as a driver
    of the new one. Listfiles parsing happens in a new
    `args_parser_add_listfile` function that uses `tcc_open`/`tcc_close/inp`
    for buffered file input.
2016-04-13 07:05:38 +03:00
seyko
a1a5c81e6c win32: Add missing header files for nginx compilation
From: Vlad Vissoultchev
    Date: Tue, 12 Apr 2016 21:02:43 +0300
    Subject: win32: Add missing header files for nginx compilation

    The new ones are hoisted from mingw-w64 as most other headers under
    `win32/include/winapi`
2016-04-13 06:51:59 +03:00
seyko
52d194a1e6 VS2015 solution and project files
From: Vlad Vissoultchev
    Date: Mon, 11 Apr 2016 01:32:28 +0300
    Subject: Add VS2015 solution and project files to `win32/vs2015`
             directory

    This allows release/debug builds for both x86 and x64 targets. Some
    warnings had to be suppressed.

    Output libtcc.dll and tcc.exe are copied to parent `win32` directory
    w/ a post-build action.
2016-04-13 06:29:24 +03:00
seyko
b5b3e89f9e Fix pragma once guard
From: Vlad Vissoultchev
    Date: Mon, 11 Apr 2016 01:26:32 +0300
    Subject: Fix pragma once guard when compiling multiple source files

    When compiling multiple source files directly to executable cached
    include files guard was incorrectly checked for TOK_once in ifndef_macro
    member.

    If two source files included the same header guarded by pragma once, then
    the second one erroneously skipped it as `cached_includes` is not cleared
    on second `tcc_compile`
2016-04-13 06:17:02 +03:00
seyko
b0296139a8 fix for the -dM patch
assign fopen("/dev/null","w") to the s->ppfp insteed of NULL
2016-04-13 05:17:13 +03:00
seyko
f869dfb47f document -dM in "tcc -h" output 2016-04-13 04:27:27 +03:00
seyko
131d776d66 revert of the 'Identifiers can start and/or contain'
When tccboot kernels compiles with
    'Identifiers can start and/or', this kernel don't start.
    It is hard to find what is wrong.

    PS: there was no test for identifiers in *.S with '.'
2016-04-13 03:52:07 +03:00
Vlad Vissoultchev
174d06a3ff Skip math library if not found when -lm option is used
This only silences "cannot find library" error and allows Makefiles targeting gcc to not complain about missing libraries

If there is custom libm then standard handling applies.
2016-04-08 12:18:31 +03:00
Vlad Vissoultchev
e946eb2a41 Implement -dM preprocessor option as in gcc
There was already support for -dD option but in contrast -dM dumps only `#define` directives w/o actual preprocessor output.

The original -dD output differs from gcc output by additional comment in front of `#define`s so this quirk is left for -dM as well.
2016-04-06 18:57:11 +03:00
Vlad Vissoultchev
0691b7630b tccgen.c: Allow type attributes to prefix enum/struct/union name
From gcc docs: "You may also specify attributes between the enum, struct or union tag and the name of the type rather than after the closing brace."

Adds `82_attribs_position.c` in `tests/tests2`
2016-04-06 14:32:52 +03:00
seyko
effc7d9ed4 cleaning "Identifiers can start and/or contain"
more logical algorithm of the isidnum_table[] changing
2016-04-05 15:06:47 +03:00
seyko
983c40f58b compilation speed of the tccboot correction
we use gnu extension "case 0x80 ... 0xFF" for tcc & gcc
    and perform test
        if(c & 0x80)
    for other compilers
2016-04-05 13:38:53 +03:00
seyko
936819a1b9 utf8 in identifiers
made like in pcc
    (pcc.ludd.ltu.se/ftp/pub/pcc-docs/pcc-utf8-ver3.pdf)
    We treat all chars with high bit set as alphabetic.
    This allow code like

    #include <stdio.h>
    int Lefèvre=2;
    int main() {
        printf("Lefèvre=%d\n",Lefèvre);
        return 0;
    }
2016-04-05 13:05:09 +03:00
seyko
c9473a7529 nocode_wanted with while/for inside ({})
a test included.
2016-04-05 11:47:20 +03:00
seyko
5a704457e2 optimization of the previous patch
compilation speed of the tccboot restored
    (patch remove testing of the parse_flags in loop)
2016-04-05 11:19:09 +03:00
seyko
d3e85e80fd Identifiers can start and/or contain '.' in *.S
modified version of the old one which don't allow '.'
    in #define Identifiers. This allow correctly preprocess
    the following code in *.S

        #define SRC(y...)               \
        9999: y;                        \
        .section __ex_table, "a";       \
        .long 9999b, 6001f      ;       \
        // .previous

        SRC(1: movw (%esi), %bx)
        6001:

    A test included.
2016-04-05 10:43:50 +03:00
seyko
21665f4338 describe -fnormalize-inc-dirs in tcc-doc.texi 2016-04-04 19:22:52 +03:00
seyko
5278d217ff R_386_COPY
This reloction must copy initialized data from the library
    to the program .bss segment. Currently made like for ARM
    (to remove noise of defaukt case). Is this true?
2016-04-03 18:13:53 +03:00
seyko
41785a0bf9 -fnormalize-inc-dirs
remove non-existent or duplicate directories from include paths
    if -fnormalize-inc-dirs is specified. This will help
    to compile current coreutils package
2016-04-03 11:42:15 +03:00
seyko
2bf43b5483 reverse of the "Identifiers can start and/or contain '.'"
- Identifiers can start and/or contain '.' in PARSE_FLAG_ASM_FILE
    - Move all GAS directives under TOK_ASMDIR prefix

    This patches breaks compilation of the tccboot (linux 2.4.26
    kernel). A test.S which fails with this patches:

    #define SRC(y...) \
    9999: y; \
    .section __ex_table, "a"; \
    .long 9999b, 6001f<---->; \
    .previous

    SRC(1:<>movw (%esi), %bx<------>)
    // 029-test.S:7: error: macro 'SRC' used with too many args
2016-04-03 11:01:05 +03:00
Michael Matz
80343ab7d8 Fix assignment to/from volatile types
Code like this was broken:

   char volatile vi = i;

See testcase, happens in ideosyncratic legacy code sprinkling
volatile all over.
2016-03-26 17:57:22 +01:00
Michael Matz
8fc5a6a2a4 Fix tokenization of TOK_DOTS
We really need to use PEEKC during tokenization so as to
skip line continuations automatically.
2016-03-24 15:58:32 +01:00
Michael Matz
f85db99ff0 Fix type parsing
the check on incomplete struct/union/enum types was too early,
disallowing mixed specifiers and qualifiers.  Simply rely on
the size (->c) field for that.  See testcases.
2016-03-24 15:44:01 +01:00
Vlad Vissoultchev
aa1ed616eb Move all GAS directives under TOK_ASMDIR prefix to include leading '.'
Use only these tokens in `asm_parse_directive` and don't recycle others' tokens (like TOK_SECTION1)
2016-03-15 10:00:50 +02:00
Vlad Vissoultchev
05ec6654a7 Identifiers can start and/or contain '.' in PARSE_FLAG_ASM_FILE
Including labels, directives and section names
2016-03-14 18:37:39 +02:00
Vlad Vissoultchev
17395ea507 tccpp.c: Fix failing PPTest 03 by reverting rogue modification in macro_arg_subst 2016-03-14 18:26:41 +02:00
Vlad Vissoultchev
fa2472c172 Fix tests Makefiles on Windows
Compiled tcc.exe location is under $(top_srcdir)/win32
2016-03-14 18:11:49 +02:00
Vlad Vissoultchev
5175b1ad87 Use proper ifdef for x64 check in winnt.h 2016-03-14 18:07:38 +02:00
Vlad Vissoultchev
712eca44d5 Revert spawnvp param cast and use no-incompatible-pointer-types in build-tcc.bat 2016-03-14 18:06:42 +02:00
Vlad Vissoultchev
9d778c7bb6 Keep lvalue category on structs when evaluating ternary operator 2016-03-13 04:32:18 +02:00
Vlad Vissoultchev
32755dbea9 Migrate static STRING_MAX_SIZE buffers to CString instances for large macros expansion 2016-03-13 04:26:45 +02:00
Vlad Vissoultchev
d715ebdae0 Add x64 SEH decls. Add exports to kernel32.def 2016-03-13 04:23:15 +02:00
Vlad Vissoultchev
95aac21130 Move WIN32_LEAN_AND_MEAN to windows.h (silence redeclarations) 2016-03-13 04:21:23 +02:00
Vlad Vissoultchev
2dc7161453 Win32 build script handles x64 and debug params 2016-03-13 04:19:32 +02:00
Vlad Vissoultchev
8e4d64be2f Silence FIXME and compiler warning 2016-03-13 04:18:43 +02:00
Michael Matz
ceccd3ead3 tccgen.c: Fix flex array members some more
Last fix didn't work for function f1int in the added testcase.
2016-03-11 22:35:44 +01:00
Henry Kroll III
7e0ad4fdd2 tccgen.c: off by one in flexible array members
tccgen.c: fix fexible array member breaking struct alignment
2016-03-10 08:28:26 -08:00
Edmund Grimley Evans
f75f89fc8f tccgen.c: In parse_btype, handle type qualifiers applied to arrays.
Also add some test cases in tests/tests2/39_typedef.c.
2016-01-11 07:51:58 +00:00
Edmund Grimley Evans
541b33591c CodingStyle: Remove reference to misaligned struct CString.
This was fixed by 1c2dfa1 on 2015-11-21.
2016-01-06 19:09:28 +00:00
Thomas Preud'homme
933c2235e5 i386: Add support for new psABI relocation
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.
2015-12-27 12:09:45 +08:00
Michael Matz
f15c0a9333 x86-64: fix shared libs
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.
2015-12-17 19:41:20 +01:00
Michael Matz
e264243adc x86-64: Define symbol constant for new relocs
Whoops, we have our own <elf.h> copy, so I can just as well add
the symbol defines for the relocs instead of hard-coding numbers
in tccelf.c.
2015-12-17 07:30:35 +01:00
Michael Matz
c4d0498b3a x86-64: Add support for new psABI relocations
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.
2015-12-17 07:17:34 +01:00
Vincent Lefevre
d1e15514aa Fixed a dependency (error with make -j8).
Signed-off-by: Vincent Lefevre <vincent@vinc17.net>
2015-12-15 13:47:07 +01:00
Edmund Grimley Evans
1c2dfa1f4b Change the way struct CStrings are handled.
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.
2015-11-26 12:40:50 +00:00
Edmund Grimley Evans
4886d2c640 TODO: Add two issues. 2015-11-26 12:31:23 +00:00
Edmund Grimley Evans
99372bb1d3 tccgen.c: Give error if statement expression found when const wanted.
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); }
2015-11-26 12:28:42 +00:00
Edmund Grimley Evans
51c3465a49 tcc.h: Change order of built-in include paths: put TCC's own dir first.
There may be compiler-specific header files that should override
system headers. See TCC's include paths by running "tcc -vv".
2015-11-23 12:50:16 +00:00
Edmund Grimley Evans
7301b42e36 tccgen.c: Try to make sizeof(!x) work.
tests/tests2/27_sizeof.*: Add test.
2015-11-22 00:00:36 +00:00
Edmund Grimley Evans
737f984213 tccgen.c: Bug fix for 992cbda and 3ff77a1: set nocode_wanted.
tests/tests2/78_vla_label.*: Add test.
2015-11-21 23:58:58 +00:00
Edmund Grimley Evans
cfef9ac3f5 TODO: Add note on handling of floating-point values. 2015-11-21 10:35:47 +00:00
Edmund Grimley Evans
dd40d6a068 TODO: Add some issues. 2015-11-21 00:04:58 +00:00
Edmund Grimley Evans
5bd5fd488d CodingStyle: Add notes on language and testing. 2015-11-20 23:41:01 +00:00
Edmund Grimley Evans
3ff77a1d6f Improve constant propagation with "&&" and "||". 2015-11-20 23:33:49 +00:00
Edmund Grimley Evans
c7067aeb84 tccelf.c: On arm64, use read64le, and use uint64_t to check range. 2015-11-20 23:29:08 +00:00
Edmund Grimley Evans
4ae626451e Bug fix for commit 553242c18a.
In gtst, vtop->c.i is not usually zero, but it is when compiling:

int f(void) { return 1 && 1 ? 1 : 1; }
2015-11-20 23:17:24 +00:00
grischka
8dd1859176 tccpp: allow .. in token stream
for gas comments lonely on a line such as

    # .. more stuff

where tcc would try to parse .. as a preprocessor directive

See also: 0b3612631f
2015-11-20 18:25:00 +01:00
grischka
0b3612631f tccpp: cleanup #include_next
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
2015-11-20 12:05:55 +01:00
grischka
54cf57ab1a tccgen: asm_label cleanup
- avoid memory allocation by using its (int) token number
- avoid additional function parameter by using Attribute

Also: fix some strange looking error messages
2015-11-20 11:22:56 +01:00
Edmund Grimley Evans
992cbda8d0 tccgen.c: Recognise constant expressions with conditional operator.
tests/tests2/78_vla_label.c: Check that int a[1 ? 1 : 1] is not a VLA.
2015-11-20 00:24:46 +00:00
Edmund Grimley Evans
30c54c9d43 tccgen.c: In parse_btype, handle typedef types with added type qualifiers.
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);
2015-11-19 23:45:33 +00:00
Edmund Grimley Evans
58a34d22c9 tccgen.c: Improvements to type_to_str (only used for error messages).
1. Handle array types.
2. Print the type qualifiers of pointers.
2015-11-19 23:35:36 +00:00
Edmund Grimley Evans
ba99a70cd8 Trivial changes to avoid some compiler warnings. 2015-11-19 18:26:47 +00:00
Edmund Grimley Evans
553242c18a Replace pointer casts with calls to (read|write)(16|32|64)le.
This stops UBSan from giving runtime misaligned address errors
and might eventually allow building on a non-little-endian host.
2015-11-19 18:21:14 +00:00
Edmund Grimley Evans
5d496b1695 tccgen.c: Avoid undefined behaviour in constant propagation. 2015-11-17 19:34:31 +00:00
Edmund Grimley Evans
569fba6db9 Merge the integer members of union CValue into "uint64_t i". 2015-11-17 19:09:35 +00:00
Edmund Grimley Evans
3712c958f4 tests/tests2/79_vla_continue.c: Fix off-by-one error. 2015-11-13 21:49:29 +00:00
Edmund Grimley Evans
c39bc9caa7 libtcc.c: Completely replace tcc_normalize_inc_dirs. 2015-11-11 21:18:01 +00:00
Edmund Grimley Evans
a7334f791d arm64-gen.c: Avoid some cases of undefined behaviour.
Also make some functions more portable.
2015-11-09 23:06:05 +00:00
Edmund Grimley Evans
c52128c581 tccelf.c: Avoid two trivial instances of undefined behaviour. 2015-11-09 22:57:58 +00:00
Avi Halachmi (:avih)
951c23f257 win: include dirs: add some docs, minor refactor 2015-11-08 16:28:00 +02:00
seyko
37e815eee1 lib/Makefile: filter-out -b flag from XFLAGS
to build tcc with bound checking
    ./configure --cc=tcc --extra-cflags-b
2015-11-08 12:26:17 +03:00
seyko
763dd22b35 fix tcc_mormalize_inc_dirs naming 2015-11-08 11:42:56 +03:00
Avi Halachmi (:avih)
ec67dc482f win: fix incorrect directory detection
Allow other flags too...
2015-11-08 04:33:30 +02:00
Avi Halachmi (:avih)
acbab220c8 win: fix dir comparison during include dirs processing
Use native Windows API via wrapper with stat-like API.
2015-11-08 03:56:25 +02:00
Avi Halachmi (:avih)
9d33388b29 win: libm: add implementation for round/fmin/fmax and variants
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.
2015-11-07 22:31:57 +02:00
Avi Halachmi (:avih)
9c52ba48b3 win: math.h: fix fpclassify/signbit/etc - use C instead of broken asm
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
2015-11-07 22:18:46 +02:00
Avi Halachmi (:avih)
6e261a107c win: math.h: isnan: use macro, similar to others (still broken)
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.
2015-11-07 22:17:21 +02:00
Avi Halachmi (:avih)
7307a6a3cb Revert "win32/include/math.h: remoing a "t" modifier usage"
This reverts commit 45bc505968.

The new asm code did not work as expected. Coordinated with seiko.
2015-11-07 21:30:56 +02:00
seyko
8fc9c79705 TOK_INCLUDE: fix for the "normalize inc dirs"
A case for the absolute path: prevent an error after openening
2015-11-06 02:50:36 +03:00
seyko
7cb921a44b TOK_INCLUDE: streamline
goto removed
2015-11-06 02:40:14 +03:00
Edmund Grimley Evans
eb00777309 tcctok.h: Put TOK_memmove in the correct places (I hope).
This should have been part of b051549. Someone should test on ARM.
2015-11-05 19:37:04 +00:00
Edmund Grimley Evans
7f0b798418 tcctok.h: Revert 41408f2, which moved TOK_memmove. 2015-11-05 19:33:46 +00:00
seyko
97916c9d04 tcc.h: remove CONFIG_TCCBOOT part
curremtly no one will try to compile a linux kernel
    from the boot loader. With current tcc it is not
    possible w/o additional tuning.
2015-11-05 20:30:51 +03:00
seyko
41408f2104 fix for the "tccgen.c: Use memmove for struct assignment"
./configure --enable-cross
    make
    tcc -o i386-tcc tcc.c
    tcc -o x86_64-tcc tcc.c
    tcc -o i386-win-tcc tcc.c
    In file included from tcc.c:22:
    In file included from libtcc.c:39:
    tccgen.c:2580: error: 'TOK_memmove' undeclared
2015-11-05 20:24:04 +03:00
seyko
0ad87a094c fix for the previous commit
a cross-compilation from unix to win32 need a "sys/stat.h"
    include file
2015-11-05 20:14:42 +03:00
seyko
a6276b7a78 normalize inc dirs, symplify include_next
include dirs are prepared as in gcc
    - for each duplicate path keep just the first one
    - remove each include_path that exists in sysinclude_paths

    include_next streamlined by introducing inc_path_index
    in the BufferedFile
2015-11-05 19:52:49 +03:00
seyko
45bc505968 win32/include/math.h: remoing a "t" modifier usage
replaced by loading a float argument from memory and
    using the "m" modifier
2015-11-05 14:27:41 +03:00
Edmund Grimley Evans
f7dd3d49cc lib/libtcc1.c: Replace "long" with "unsigned int" in union float_long. 2015-11-04 23:22:00 +00:00
Edmund Grimley Evans
24308fd292 tccpp.c: In TOK_GET, add comment warning about illegal cast.
Also, in tok_str_add2, use memcpy instead of the illegal cast.

Unfortunately, I can't see an easy way of fixing the bug.
2015-11-04 20:27:54 +00:00
Edmund Grimley Evans
20f0c179da tccpp.c: Define and use tok_last for checking if last token is space. 2015-11-04 20:25:26 +00:00
Edmund Grimley Evans
b051549f2e tccgen.c: Use memmove for struct assignment: dest and src may be equal. 2015-11-04 20:23:17 +00:00
Edmund Grimley Evans
8eab556ac5 tccgen.c: Fix memory leak involving asm_label. 2015-11-04 20:22:30 +00:00
Edmund Grimley Evans
9bf0e57509 tests/tcctest.c: Fix up format strings. 2015-11-04 20:20:26 +00:00
Edmund Grimley Evans
f4082851ea Enable variable-length arrays on arm64.
arm64-gen.c: Implement gen_vla_sp_save, gen_vla_sp_restore, gen_vla_alloc.
tests/Makefile: Run vla_test on arm64.
2015-10-31 11:04:52 +00:00
seyko
35e715a1e3 defined twice: revert
An error message is changed to suggest -fcommon
2015-10-29 17:10:04 +03:00
seyko
c07785a1ea comment out tcc_error_noabort("'%s' defined twice"...
gcc-3.4.6 don't give such error by default
    example file1
	char __version_303_xxxxxxxx;
	void func1() {}
    example file2
	char __version_303_xxxxxxxx;
	void func2() {}
	int main() { return 0; }
2015-10-25 00:41:17 +03:00
seyko
12f94f2770 include/stddef.h: define NULL only if undefined 2015-10-25 00:19:12 +03:00
seyko
f3ce1be333 tcc help output for the -xc -xa - options 2015-10-24 23:39:17 +03:00
seyko
003c532bf3 fix for the #include_next, v4 (final)
This version looks rigth. Comparing to the original
    algorithm:

    1) Loop breaking. We remember a start point after wich
    we can try next path. Do not search include stack after
    this.

    2) But compare next file patch with the start point.
    Skip if it the same. Remove "./" before comparing.

    PS: a problems with compaling a coreutils-8.24.51-8802e
    remain. There are errors messages like:
    src/chgrp
        src/chown-core.c:42: multiple definition of `make_timespec'
        src/chgrp.c:42: first defined here
    A problem is in the lib/config.h
        #define _GL_INLINE_ extern inline // gcc
        #define _GL_INLINE_ inline        // tcc

    A long description from the lib/config.h
    * suppress extern inline with HP-UX cc, as it appears to be broken
    * suppress extern inline with Sun C in standards-conformance mode
    * suppress extern inline on configurations that mistakenly use
      'static inline' to implement functions or macros in standard
      C headers like <ctype.h>.

    GCC and Clang are excluded from this list. Why not tcc?
2015-10-20 07:32:53 +03:00
seyko
ad1c01f96c fix for the #include_next, v3
don't give an error and simply ingnore directive
  if we detect a loop of the #include_next.

  With this aproach coreutils-8.24.51-8802e
  compiles, but with errors:
  	lib/libcoreutils.a: error: 'xnmalloc' defined twice
	lib/libcoreutils.a: error: 'xnrealloc' defined twice
2015-10-19 17:55:26 +03:00
seyko
6b9490b6ff fix for the #include_next, v2
A more correct fix. This one don't break old logic.
    But if include file is not found, we try to search
    again with the new compare rule.

    A description of the problem:
    http://permalink.gmane.org/gmane.comp.compilers.tinycc.devel/2769
2015-10-17 15:48:10 +03:00
seyko
ad524bb6c7 reverse a previous patch
a next version of the patch will follow
2015-10-17 15:32:33 +03:00
seyko
285292992f fix for the #include_next
skip include file only if include_file_name=current_file_name
2015-10-17 14:45:51 +03:00
seyko
c3975cf27c parsing "..." sequence
don't panic with
	error: '.' expected
    if there is only two '.' chars. Return tok='.' in such case.
    An asm code to test:
	jz	do_move0	# .. then we have a normal low
				# .. or else we have a high
2015-10-17 13:54:58 +03:00
Edmund Grimley Evans
f0b7566181 tccelf.c: Reset sym after call to build_got.
The call to build_got can cause symtab_section->data to be reallocated
(build_got -> add_elf_sym -> put_elf_sym -> section_ptr_add ->
section_realloc -> tcc_realloc). This is not obvious on a cursory
inspection, but fortunately Valgrind spotted it immediately.
Are there other, similar bugs that Valgrind did not detect?
2015-10-16 20:33:41 +01:00
Edmund Grimley Evans
743684fe39 tccpp.c: Avoid infinite loop on: printf '/**' | ./tcc - 2015-10-15 19:02:58 +01:00
Edmund Grimley Evans
c899659d39 tccgen.c: Remove undefined shift of negative signed value. 2015-10-15 19:02:57 +01:00
Edmund Grimley Evans
eafd7a7d3b Correct prototype: void __clear_cache(void *, void *). 2015-10-15 19:02:54 +01:00
Kamil Rytarowski
a16f862cf6 Define CONFIG_TCC_ELFINTERP on NetBSD as /usr/libexec/ld.elf_so 2015-10-11 12:22:41 +02:00
Kamil Rytarowski
6cb74ecacf Define __WINT_TYPE__ as int in NetBSD 2015-10-11 11:59:20 +02:00
Kamil Rytarowski
5860b639c6 Add support for -D__NetBSD__ 2015-10-11 03:12:35 +02:00
seyko
00ba4b7625 win32: UUID typedef added 2015-09-25 03:42:44 +03:00
seyko
8077f0acc7 a number as a field name (part 2)
don't crash
    a test program:
    ================
    typedef struct X { int len; } X;
    #define init(s,len)  s.len = len;
    int main(void) {
	X myX;
	init(myX,10);
	return 0;
    }
    ================
    After a patch:
    	error: field name expected
2015-09-25 02:31:34 +03:00
seyko
e7e7a0d301 a number as a field name
a test program:
    ========
    typedef struct X { int len; } X;
    int main(void) {
       X myX;
       myX.10 = 10;
       return 0;
    }
    ========
    Error message before a patch:
	error: ';' expected (got "(null)")
    After a patch:
	error: field name expected
2015-09-25 01:44:23 +03:00
seyko
eb870b006c SSE opcodes to TCC assembler (i386, x86_64)
patch from Anaël Seghezzi
    a test program:
    ============================
    #include <stdio.h>
    struct fl4{ float x, y, z, w; };
    void asm_test(void)
    {
	struct fl4 v1, v2, v3;
	v1.x = 0.1;
	v1.y = 0.2;
	v1.z = 0.4;
	v1.w = 0.3;
	v2.x = 0.11;
	v2.y = 0.0;
	v2.z = 0.01;
	v2.w = 0.04;
	asm volatile (
	    "movups %0, %%xmm0;"
	    "movups %1, %%xmm1;"
	    "addps %%xmm1, %%xmm0;"
	    "movups %%xmm0, %2"
	:: "g" (v1), "g" (v2), "g" (v3) : "memory");
	printf("sse fl4 add : %f %f %f %f\n", v3.x, v3.y, v3.z, v3.w);
	printf("expected : %f %f %f %f\n", v1.x+v2.x, v1.y+v2.y, v1.z+v2.z, v1.w+v2.w);
    }
    int main() { asm_test(); }
    /*
	sse fl4 add : 0.210000 0.200000 0.410000 0.340000
	expected : 0.210000 0.200000 0.410000 0.340000
    */
    ============================
2015-09-23 14:58:06 +03:00
gus knight
8f620c8af8 Adding two more people to the RELICENSING file.
They also responded to my mail with a YES.
2015-07-31 16:56:23 -04:00
gus knight
ef3d38c5c9 Revert "fix-mixed-struct (patch by Pip Cet)"
This reverts commit 4e04f67c94. Requested by grischka.
2015-07-29 16:57:41 -04:00
gus knight
89ad24e7d6 Revert all of my changes to directories & codingstyle. 2015-07-29 16:57:12 -04:00
gus knight
5a16f5ea98 Fix Makefile. 2015-07-29 09:59:17 -04:00
gus knight
7f5b95ea32 Fix formatting breakage from "rogue tabs" commit. 2015-07-29 09:59:11 -04:00
gus knight
271abe7117 Add a root Makefile for running targets in subdirectories. 2015-07-29 09:59:07 -04:00
gus knight
770fd39bd1 Relicensing TinyCC.
I've been sending a lot of mails out asking contributors if they
approve the license change, so I'm adding the ones who reply here.
2015-07-29 09:58:59 -04:00
Vincent Lefevre
07c6263732 typo in RELICENSING 2015-07-29 15:29:22 +02:00
Vincent Lefevre
e667d0cc9c Relicensing TinyCC 2015-07-29 15:24:56 +02:00
gus knight
47e06c6d4e Reorganize the source tree.
* Documentation is now in "docs".
 * Source code is now in "src".
 * Misc. fixes here and there so that everything still works.

I think I got everything in this commit, but I only tested this
on Linux (Make) and Windows (CMake), so I might've messed
something up on other platforms...
2015-07-27 16:03:25 -04:00
gus knight
694d0fdade clang-format on arm-gen.c and tcccoff.c.
They now mostly follow the same coding style as everything else.
2015-07-27 14:26:15 -04:00
gus knight
9e1b6bf517 Update CodingStyle. 2015-07-27 14:25:50 -04:00
gus knight
d6b64e2574 Clean up lots of rogue tabs.
Still some more tabs to be taken care of. arm-gen.c and tcccoff.c
have so many style issues that I'm just going to throw clang-format
at them.
2015-07-27 14:14:41 -04:00
gus knight
41031221c8 Trim trailing spaces everywhere. 2015-07-27 12:43:40 -04:00
gus knight
5e67f24e6b Relicensing TinyCC.
I haven't contributed anything yet, but I might as well add this :)
2015-07-27 12:39:54 -04:00
seyko
4e04f67c94 fix-mixed-struct (patch by Pip Cet)
Jsut for testing. It works for me (don't break anything)
    Small fixes for x86_64-gen.c in "tccpp: fix issues, add tests"
    are dropped in flavor of this patch.

    Pip Cet:

    Okay, here's a first patch that fixes the problem (but I've found
    another bug, yet unfixed, in the process), though it's not
    particularly pretty code (I tried hard to keep the changes to the
    minimum necessary). If we decide to actually get rid of VT_QLONG and
    VT_QFLOAT (please, can we?), there are some further simplifications in
    tccgen.c that might offset some of the cost of this patch.

    The idea is that an integer is no longer enough to describe how an
    argument is stored in registers. There are a number of possibilities
    (none, integer register, two integer registers, float register, two
    float registers, integer register plus float register, float register
    plus integer register), and instead of enumerating them I've
    introduced a RegArgs type that stores the offsets for each of our
    registers (for the other architectures, it's simply an int specifying
    the number of registers). If someone strongly prefers an enum, we
    could do that instead, but I believe this is a place where keeping
    things general is worth it, because this way it should be doable to
    add SSE or AVX support.

    There is one line in the patch that looks suspicious:

             } else {
                 addr = (addr + align - 1) & -align;
                 param_addr = addr;
                 addr += size;
    -            sse_param_index += reg_count;
             }
             break;

    However, this actually fixes one half of a bug we have when calling a
    function with eight double arguments "interrupted" by a two-double
    structure after the seventh double argument:

    f(double,double,double,double,double,double,double,struct { double
    x,y; },double);

    In this case, the last argument should be passed in %xmm7. This patch
    fixes the problem in gfunc_prolog, but not the corresponding problem
    in gfunc_call, which I'll try tackling next.
2015-05-14 07:32:24 +03:00
seyko
101cc8747f win32/include/winapi changes from https://github.com/run4flat/tinycc.git
just for testing. Is it needed? I'm not a MSYS citizen.

        run4flat is a tcc fork by David Mertens that knows how to work with
        multiple symbol tables. Excelent work. A good descriptions of the
        tcc internals inside a code comments.
2015-05-14 01:27:46 +03:00
seyko
80322adaa0 redo of the -dD option
functionality was broken some time ago and was removed
    by the "tccpp: fix issues, add tests"

    fix: LINE_MACRO_OUTPUT_FORMAT_NONE in pp_line()
    means: output '\n' and not "don't output at all"
2015-05-13 12:16:00 +03:00
seyko
cf92f7aacb some -bench fixes
print stats to stderr, not to stdout
2015-05-12 22:02:51 +03:00
seyko
06e0753fce minor pp optimizations
* remove free_defines() from tcc_preprocess()
        all cleanup will be done in tcc_delete
    * move a preprocessor file closing to tcc_delete too
2015-05-12 21:32:32 +03:00
seyko
1234beccb8 restore a max memory usage printing for a new MEM_DEBUG when -bench 2015-05-12 16:07:09 +03:00
seyko
c52e1a9af5 SYMBOL_NAME_LABEL(X) X##:
In the linux kernel sources:
      #ifdef __STDC__
        #define SYMBOL_NAME_LABEL(X) X##:
      #else
        #define SYMBOL_NAME_LABEL(X) X/**/:
      #endif
    tcc is a STDC compiler and must handle 'X##:' case.
2015-05-12 15:24:41 +03:00
seyko
121e95d115 a new version of the MEM_DEBUG 2015-05-12 11:56:39 +03:00
seyko
a98fd13090 a mem leak fix for "ability to compile multiple *.c files with -c switch"
A new version of the MEM_DEBUG will be submitted next. This version is
    not depend on the malloc_usable_size() presense in the libc and
    print a places where a leaked chunks of memory was allocated.
2015-05-12 10:58:04 +03:00
seyko
ae09051c81 allow to use MEM_DEBUG with libtcc 2015-05-11 18:05:31 +03:00
seyko
cb7e820eae tcc_add_dll is not used if TCC_TARGET_PE
after "tccpp: fix issues, add tests"
2015-05-10 11:37:36 +03:00
seyko
ff06d4258e define __OPTIMIZE__ if -ON (N != 0)
this is gcc behaviour
2015-05-10 10:21:37 +03:00
seyko
c497f9c82c warn if multile -o option is given 2015-05-10 10:13:35 +03:00
seyko
87a0109604 restore "./configure --enable-tcc32-mingw" on linux
commit "tccpp: fix issues, add tests" also include
        - configure/Makefile : build on windows (MSYS) was broken
    which breaks a cross compilation on linux
2015-05-10 09:57:11 +03:00
grischka
30df3189b1 tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
  didn't work well)

Based partially on ideas / researches from PipCet

Some issues remain with VA_ARGS macros (if used in a
rather tricky way).

Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=')  GCC does that, other compilers don't.

 * cleanups
  - #line 01 "file" / # 01 "file" processing
  - #pragma comment(lib,"foo")
  - tcc -E: forward some pragmas to output (pack, comment(lib))
  - fix macro parameter list parsing mess from
    a3fc543459
    a715d7143d
    (some coffee might help, next time ;)
  - introduce TOK_PPSTR - to have character constants as
    written in the file (similar to TOK_PPNUM)
  - allow '\' appear in macros
  - new functions begin/end_macro to:
      - fix switching macro levels during expansion
      - allow unget_tok to unget more than one tok
  - slight speedup by using bitflags in isidnum_table

Also:
  - x86_64.c : fix decl after statements
  - i386-gen,c : fix a vstack leak with VLA on windows
  - configure/Makefile : build on windows (MSYS) was broken
  - tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 14:29:39 +02:00
Philip
70a6c4601e VLA code: minor fix
Don't try to call get_flags() on the mob branch, where it's not defined.
2015-05-04 03:42:02 +00:00
seyko
c75d0deecf VLA code minor fix 2015-05-04 04:19:24 +03:00
seyko
999274ca90 a lot simpler VLA code
Author: Philip <pipcet@gmail.com>
    Our VLA code can be made a lot simpler (simple enough for
    even me to understand it) by giving up on the optimization idea, which
    is very tempting. There's a patch to do that attached, feel free to
    test and commit it if you like. (It passes all the tests, at least
2015-05-04 04:09:05 +03:00
seyko
fca58734fb -traditional and -iwithprefix options 2015-05-03 20:10:57 +03:00
seyko
576aeb3aa9 fix "tcc test.c -Wl,,--oformat,binary"
set linker options only when "s->output_type == TCC_OUTPUT_EXE"
    otherwise tcc will produce a wrong object file
2015-05-03 14:17:18 +03:00
seyko
2ba219f781 fix "tcc test.c -UAAA -UBBB"
no need to call tcc_free() inside tcc_undefine_symbol()
    Otherwise we get segmentation fault inside tcc_delete()
2015-05-03 13:58:27 +03:00
Philip
929d171f47 Mostly revert "tccpp.c: minor fix I'd accidentally not committed"
This reverts commit 27ec4f67a3.

Sorry about that, I included changes which are still being tested, by
accident.
2015-05-02 20:30:07 +00:00
Philip
27ec4f67a3 tccpp.c: minor fix I'd accidentally not committed
Sorry about that. This should definitely fix Sergey's issue.
2015-05-02 17:14:07 +00:00
Philip
3b4c42c3c0 minor fix
Fixes the issue reported by Sergey at
http://lists.nongnu.org/archive/html/tinycc-devel/2015-05/msg00007.html

I hope.
2015-05-02 16:49:12 +00:00
Philip
823d0583dc tccpp.c: unterminated macro argument error message
#define a(x) x
    a((

would produce "error: , expected" when what's actually expected is a
')'.
2015-05-02 14:47:11 +00:00
Philip
2f90db434e tccpp.c: fix GNU comma handling
This requires moving TOK_PLCHLDR handling, but the new logic should make
things easier even if (when?) GNU comma handling is removed.

(Somewhat confusingly, GCC no longer supports GNU commas. See
http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html for a description
of past and current GCC behaviour.)
2015-05-02 14:27:49 +00:00
Philip
2f50cefbd4 tccpp.c: restore whitespace after failed macro
This fixes test7 described in:

http://lists.nongnu.org/archive/html/tinycc-devel/2015-05/msg00002.html

Note that the current code still adds excessive forced blank characters
to its output, so this patch might not change visible behaviour.
2015-05-02 13:55:42 +00:00
Philip
a6e6a954f5 tccpp.c: correct # stringification
Fix handling of escape characters, spaces, and line feeds in macros or
macro arguments that might yet be subject to # stringification.

Should this be an -f option? I think memory usage increases only very
slightly (in particular, while line feeds, stray \s, and spaces are
preserved, comments are not), so it's probably not worth it to make it
one.

Note that macro_subst now checks for stray \s which are still left in
the input stream after macro substitution, if desired.

This patch depends on the previous patch, so if you revert that, please
revert this patch, too.

See http://lists.nongnu.org/archive/html/tinycc-devel/2015-05/msg00002.html
2015-05-02 13:19:14 +00:00
Philip
0877ba7cbf tccpp.c: parse flag to accept stray \
This adds a PARSE_FLAG_ACCEPT_STRAYS parse flag to accept stray
backslashes in the source code, and uses it for pure preprocessing.

For absolutely correct behaviour of # stringification, we need to use
this flag when parsing macro definitions and in macro arguments, as
well; this patch does not yet do so. The test case for that is something
like

    #define STRINGIFY2(x) #x
    #define STRINGIFY(x) STRINGIFY2(x)

    STRINGIFY(\n)

which should produce "\n", not a parse error or "\\n".

See http://lists.nongnu.org/archive/html/tinycc-devel/2015-05/msg00002.html
2015-05-02 12:58:37 +00:00
Philip
a3d78b95d7 tccpp.c: fix endless loop
Perhaps a better fix would be to ensure tok is set to TOK_EOF rather
than 0 at the end of a macro stream.

This partially fixes test2 of the examples given in:
http://lists.nongnu.org/archive/html/tinycc-devel/2015-05/msg00002.html

It's still failing, but at least it's not running out of memory now.
2015-05-02 12:33:45 +00:00
Philip
1e878200f7 tccpp.c: reset spc after macro_subst_tok()
This bug doesn't seem to affect anything currently, but does interfere
with miscellaneous tccpp.c fixes for the test cases described here:

http://lists.nongnu.org/archive/html/tinycc-devel/2015-05/msg00002.html
2015-05-02 12:26:10 +00:00
Philip
3a922ad2ba tccpp.c: fix ##-in-macros logic
The old code had an inverted condition, so

    #define a(b)## b

would be accepted while

    #define a(b,c) b ## ## c

would be rejected with the confusing error message "'##' invalid at
start of macro".
2015-05-02 12:14:14 +00:00
Philip
a6b94eff79 tccpp.c: fix empty stringify
#define STRINGIFY2(x) #x
    #define STRINGIFY(x) STRINGIFY2(x)
    STRINGIFY()

should produce "", not "\301".
2015-05-01 14:48:25 +00:00
Philip
951a43ea6c fix a potential end-of-buffer issue in tccelf.c
also read characters one at a time when PARSE_DEBUG is set; after this
patch, things seem to work with that.
2015-04-30 21:35:21 +00:00
Philip
2e04fa8872 fix end-of-buffer error in tccpp.c
Quick fix for
http://lists.nongnu.org/archive/html/tinycc-devel/2015-04/msg00160.html.

I don't fully understand the intended semantics of when file->buf_ptr[0]
is valid, but the rest of the code doesn't have any obvious spots with
the same bug.

Feel free to revert this if I'm mistaken or we need to discuss this
change further.
2015-04-30 19:27:43 +00:00
Philip
4126056fbe fix vstack leak
I think this code only affects the ARM EABI target, and only when
returning small structures that might be unaligned. However, it was both
leaking vstack entries and failing to achieve what I think is its
purpose, to ensure the sret argument would be aligned properly. Both
issues fixed.
2015-04-29 21:48:30 +00:00
Philip
44c330d647 VLA fix: save stack pointer right after modification
This patch disables the optimization of saving stack pointers lazily,
which didn't fully take into account that control flow might not reach
the stack-saving instructions. I've decided to leave in the extra calls
to vla_sp_save() in case anyone wants to restore this optimization.

Tests added and enabled.

There are two remaining bugs: VLA variables can be modified, and jumping
into the scope of a declared VLA will cause a segfault rather than a
compiler error. Both of these do not affect correct C code, but should
be fixed at some point. Once VLA variables have been made properly
immutable, we can share them with the saved stack pointer and save stack
and instructions.
2015-04-28 09:23:29 +00:00
Philip
d2dd6fdbfb fix VLA/continue issue
as reported in
http://lists.nongnu.org/archive/html/tinycc-devel/2015-04/msg00131.html. Note
that this is one of two separate VLA bugs:

 A. labels aren't reached by program execution, so the stack pointer is
 never saved
 B. continue doesn't restore the stack pointer as goto does

This fixes only B. I'm not sure whether the same issue applies to break
as well as continue.

Add a test case, but disable tests #78 and #79 for now as they're not
fully fixed until the issue described in
http://lists.nongnu.org/archive/html/tinycc-devel/2015-04/msg00110.html
is resolved.
2015-04-27 16:42:27 +00:00
Philip
bd489a4815 add test case for VLA segfaults
This test obviously shouldn't segfault, but currently does so. The
problem is in the VLA code, which fails to save the stack pointer before
taking a conditional branch in some cases.

See this thread:
http://lists.nongnu.org/archive/html/tinycc-devel/2015-04/msg00130.html
2015-04-27 14:55:23 +00:00
seyko
bbcb54a1f4 replace PARSE_FLAG_ASM_COMMENTS with PARSE_FLAG_ASM_FILE
after "assign PARSE_FLAG_ASM_COMMENTS only for asm files"
    functions of this flags are identical
2015-04-27 16:36:58 +03:00
Philip
2e51f0ee63 warn about declarations after statements when compiling with gcc. 2015-04-27 13:28:03 +00:00
seyko
1351de6ad1 fixes for "tcc -E -dD"
* print "// #pragma push_macro(XXX)"
    * keep output line numbers in sync with source
      (don't output \n in printf)
2015-04-27 16:04:54 +03:00
seyko
2df290073b preprocess: "assign PARSE_FLAG_ASM_COMMENTS only for asm files"
resolve a problem with the following test.c program, tcc -E test.c

    #ifdef	_XOPEN_SOURCE
    # define __USE_XOPEN	1
    # if (_XOPEN_SOURCE - 0) >= 500
    #  define __USE_XOPEN_EXTENDED	1
    #  define __USE_UNIX98	1
    #  undef _LARGEFILE_SOURCE
    #  define _LARGEFILE_SOURCE	1
    #  if (_XOPEN_SOURCE - 0) >= 600
    #   define __USE_XOPEN2K	1
    #   undef __USE_ISOC99
    #   define __USE_ISOC99		1
    #  endif
    # else
    #  ifdef _XOPEN_SOURCE_EXTENDED
    #   define __USE_XOPEN_EXTENDED	1
    #  endif
    # endif
    #endif

    int main() {}

    // # 17 "aaa.c"
    // aaa.c:17: error: #endif without matching #if
2015-04-27 15:25:49 +03:00
Philip
2d3458363e fix another x86_64 ABI bug
The old code assumed that if an argument doesn't fit into the available
registers, none of the subsequent arguments do, either. But that's
wrong: passing 7 doubles, then a two-double struct, then another double
should generate code that passes the 9th argument in the 8th register
and the two-double struct on the stack. We now do so.

However, this patch does not yet fix the function calling code to do the
right thing in the same case.
2015-04-26 17:31:39 +00:00
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
seyko
8dbe129ab7 fix a gcc compiler warning for the previous commit
mark a constant as long long (or -std=gnu99 is needed)
2015-03-23 16:36:09 +03:00
seyko
c2efd7c53b revert a commit: Work around for the issue TCC doesn't handle -2147483648 properly
because a tcc handle now -2147483648 properly. Look a commit:
    Make integer constant parsing C99 compliant
2015-03-23 15:31:10 +03:00
seyko
bd531ec1fd A right fix for the array in struct initialization w/o '{'
Parse a type if there is only one '(' before a type token.
Otherwise a recursion will perform a job.
2015-03-23 08:27:16 +03:00
seyko
367bb6f4b7 Revert of the commit: fix for the array in struct initialization w/o '{', case 2
A right solution for this problem will follow.
2015-03-23 07:40:41 +03:00
seyko
aba2d648f4 quick fix for the native tcc on debian/ubuntu
Force to use a NATIVE_DEFINES insteed of the DEFINES for the
    native tcc. After this change we have on debian/ubuntu

    # ./x86_64-tcc -vv
    tcc version 0.9.26 (x86-64, Linux)
    install: /usr/local/lib/tcc
    crt:
      /usr/lib/x86_64-linux-gnu
    libraries:
      /usr/lib/x86_64-linux-gnu
      /usr/lib
      /lib/x86_64-linux-gnu
      /lib
      /usr/local/lib/x86_64-linux-gnu
      /usr/local/lib
    include:
      /usr/local/include/x86_64-linux-gnu
      /usr/local/include
      /usr/include/x86_64-linux-gnu
      /usr/include
      /usr/local/lib/tcc/include
    elfinterp:
      /lib64/ld-linux-x86-64.so.2

    Before this change the output was
    # ./x86_64-tcc -vv
    tcc version 0.9.26 (x86-64, Linux)
    install: /usr/local/lib/tcc
    crt:
      /usr/lib
    libraries:
      /usr/lib
      /lib
      /usr/local/lib
    include:
      /usr/local/include
      /usr/include
      /usr/local/lib/tcc/include
    elfinterp:
      /lib64/ld-linux-x86-64.so.2

    This change don't fix a cross compilers
2015-03-22 18:05:29 +03:00
seyko
b5d25654d8 configure: don't output CONFIG_LDDIR when build_cross = "yes"
This fixes i386-tcc on CentOS 7. After patch
    [root@centos7 tinycc]# ./i386-tcc -vv
    tcc version 0.9.26 (i386, Linux)
    install: /usr/local/lib/tcc
    crt:
      /usr/lib
    libraries:
      /usr/lib
      /lib
      /usr/local/lib

Before patch:
    [root@centos7 tinycc]# ./i386-tcc -vv
    tcc version 0.9.26 (i386, Linux)
    install: /usr/local/lib/tcc
    crt:
      /usr/lib64
    libraries:
      /usr/lib64
      /lib64
      /usr/local/lib64
2015-03-21 07:16:33 +03:00
seyko
63d068d3f2 skip 73_arm64,test on ARCH=x86-64: it fails on this ARCH 2015-03-20 16:01:06 +03:00
seyko
78c076a70f restore a linux 2.4.26 kernel compilation (commit 5bcc3eed7b correction)
The following check in tccgen.c is removed
    if (nocode_wanted)
	tcc_error("statement expression in global scope");
This check is introduced in commit 5bcc3eed7b and breaks compilation
of the linux 2.4.26 kernel.
2015-03-20 10:44:26 +03:00
seyko
e3851d233f correction for the previous commit
use "x86-64" as a directory name for the libtcc1.a installation when cross-compiling.
2015-03-20 09:27:59 +03:00
seyko
cfaa165e62 libtcc1.a while "configure --enable-cross"
build and install libtcc1.a for i386, x86_64 and arm64
    (libtcc1.a for x86_64 was not installed on i386)
2015-03-20 08:52:01 +03:00
seyko
3dba9cc13d "configure --enable-cross" on x86: build a libtcc1.a for x86_64 2015-03-19 13:07:02 +03:00
seyko
e2650608cd fix to allow build tcc by build-tcc.bat
move call to print_defines() from tcc.c to the libtcc.c
    define a print_defines() as a ST_FUNC
2015-03-19 08:07:35 +03:00
Edmund Grimley Evans
aa812e8745 Convert some lines from ISO-8859-1 to UTF-8.
perl -i -pe 'use Text::Iconv;
$c1 = Text::Iconv->new("utf-8", "utf-8");
$c2 = Text::Iconv->new("iso-8859-1", "utf-8");
if (!$c1->convert($_)) { $_ = $c2->convert($_); }' \
`find * -type f`
2015-03-11 07:30:03 +00:00
Edmund Grimley Evans
5de8b5638f .gitignore: Add lib/arm64. 2015-03-10 22:38:26 +00:00
Edmund Grimley Evans
0e79df499a tccgen.c: (!nocode_wanted) -> (nocode_wanted) in arm64 part. 2015-03-10 22:37:36 +00:00
Thomas Preud'homme
5bcc3eed7b Add some missing nocode_wanted guard
int i = i++ causes a segfault because of missing guard. Looking
recursively at all backend functions called from middle end several more
guard appeared to be missing.
2015-03-10 23:27:14 +08:00
Edmund Grimley Evans
68605ab4d4 lib/Makefile: Partial revert of 896a0c881a.
lib/lib-arm64.c must be compiled by tcc.
2015-03-10 14:08:42 +00:00
seyko
4ba7e5dc5a A correction for the commit: revert a grischka patch: gdb refused to know "main"
keep revert (check SHF_ALLOC) only for x86 target and keep a grishka patch for
other targets
2015-03-10 14:21:14 +03:00
seyko
896a0c881a don't use a *-tcc to compile *.S files for ARM*
A tcc for ARM* don't have an assembler. This is partial reverse of the commit
  build-libtcc1-by-tcc: use a new tcc to compile a libtcc1.c and alloca.S
2015-03-10 13:54:12 +03:00
seyko
87ec08ecc8 A native tcc for MSYS (Windows) must be i386-win-tcc.exe and not i386-tcc.exe
i386-tcc.exe is a compiler for i386 Linux. A HOST_OS variable in Makefile is
introduced and used to select a native compiler (which one to name as tcc.exe)
2015-03-10 13:39:26 +03:00
Michael Matz
25b2779c3d x86-64: Fix stdarg for large non-float structs
Some structs are passed in registers.  When they need more than
one the implementation of __va_arg on x86-64 didn't correctly account
for this.  This fixes only the cases where the structs consist of
integer types, as there the register save area is consecutive.

Fixes some tests from 73_arm64.c, but still leaves those failing
that use floating point in the large-but-regpassed structs.
2015-03-09 03:54:33 +01:00
Michael Matz
2eb4f4a3ba Remove incorrect comment
Not the code was confused, I was :)
2015-03-09 01:33:42 +01:00
Michael Matz
0ecee0072d Find libtcc1.a on arm32
The directory is called "arm", not "ARM".
2015-03-09 00:47:27 +01:00
Michael Matz
50899e30ab Fix stack overwrite on structure return
The common code to move a returned structure packed into
registers into memory on the caller side didn't take the
register size into account when allocating local storage,
so sometimes that lead to stack overwrites (e.g. in 73_arm64.c),
on x86_64.  This fixes it by generally making gfunc_sret also return
the register size.
2015-03-09 00:19:59 +01:00
Edmund Grimley Evans
d73b488401 arm64: Implement __clear_cache.
__clear_cache is defined in lib-arm64.c with a single call to
__arm64_clear_cache, which is the real built-in function and is
turned into inline assembler by gen_clear_cache in arm64-gen.c
2015-03-08 00:10:44 +00:00
Edmund Grimley Evans
03303628c7 tests/Makefile: Quote to avoid: /bin/sh: 1: [: !=: unexpected operator 2015-03-07 18:10:45 +00:00
Edmund Grimley Evans
d854dede03 arm64: Optimise some integer operations with a constant operand. 2015-03-07 17:42:08 +00:00
Edmund Grimley Evans
ac70e6b840 tccgen.c: Optimise 0<<x, 0>>x, -1>>x, x&0, x*0, x|-1, x%1.
More precisely, treat (0 << x) and so on as constant expressions, but
not if const_wanted as we do not want to allow "case (x*0):", ...

Do not optimise (0 / x) and (0 % x) here as x might be zero, though
for an architecture that does not generate an exception for division
by zero the back end might choose to optimise those.
2015-03-07 17:32:39 +00:00
Edmund Grimley Evans
9163393476 arm64-gen.c: In load(), do not sign-extend 32-bit VT_CONST. 2015-03-07 17:32:39 +00:00
seyko
8d4c861144 fix for the array in struct initialization w/o '{', case 2
a test program:

    struct {
    int a[2], b[2];
    } cases[] = {
	{ ((int)0), (((int)0)) },
	((int)0), (((int)0)) /* error: ',' expected (got ")") */
    };
    int main() { return 0; }

This commit allow to skip ')' in the decl_initializer() and to see ','
2015-03-07 09:40:12 +03:00
Edmund Grimley Evans
238e760a29 Add __builtin_return_address.
Implementation is mostly shared with __builtin_frame_address.
It seems to work on arm64, i386 and x86_64. It may need to be
adapted for other targets.
2015-03-06 21:01:14 +00:00
seyko
8764993c0d Makefile: install tcc$(EXESUF) as symlink to the $(ARCH)-tcc 2015-03-06 17:13:45 +03:00
seyko
65a4fbd1d4 Makefile: add dependencies for $($(I386_CROSS)_LINK), ...
This is another solution for the make process.
    Commit 4b92dbf923 is reverted.
2015-03-06 16:19:10 +03:00
Roy
883aafc6bb Makefile leftover of rev 44c6e99 2015-03-06 10:25:47 +08:00
seyko
d9b87c087c fixing decl_initializer() for size_only: don't eat ')'
a test program:

    struct { int c[1]; } s1[] = { (int)0       }; /* OK */
    struct { int c[1]; } s2[] = { { ((int)0) } }; /* OK */
    struct { int c[1]; } s3[] = { 0            }; /* OK */
    struct { int c[1]; } sx[] = { ((int)0)     }; /* error: ')' expected (got "}") */
    int main() { return 0; }
2015-03-05 20:18:25 +03:00
seyko
4b92dbf923 Add a dependency for a PROGS and TCCLIBS to a Makefile
Simply assume this is all *.c and *.h files in a tcc top directory.
    Now a tcc compiler is recompiled if any of this files is changed.
2015-03-05 16:39:25 +03:00
Roy
44c6e992bd Fix compiling in MinGW/MSYS 2015-03-05 09:12:42 +08:00
Edmund Grimley Evans
3fb8b14806 tccelf.c: File path component is "arm64", not "ARM64". 2015-03-04 19:43:29 +00:00
seyko
664c19ad5e partial revert of the commit 4ad186c5ef
A test program:

    /* result of the new version inroduced in 4ad186c5ef: t2a = 44100312 */
    #include<stdio.h>
    int main() {
	int t1 = 176401255;
	float f = 0.25f;
	int t2a = (int)(t1 * f); // must be 44100313
	int t2b = (int)(t1 * (float)0.25f);
	printf("t2a=%d t2b=%d \n",t2a,t2b);
	return 0;
    }
2015-03-04 16:25:51 +03:00
seyko
bfb7b0d959 --enable-tcc32-mingw option: build windows version on linux with i386-win-tcc
--enable-tcc64-mingw option: build windows version on linux with x86_64-win-tcc
2015-03-04 12:02:13 +03:00
seyko
48d12e42ad gcc options and mingw: move a gcc options detection from a makefile to the configure
+ define XCC and XAR if mingw32 defined
    + use XCC and XAR in lib/Makefile if defined
    Try "./configure --enable-mingw32; make". This must work
2015-03-04 11:47:52 +03:00
seyko
76af948623 install-clean-tuning
* Don't use /usr/local/lib/tcc/libtcc1.a for i386 and x86_64
      A $(tccdir)/i386 directory was used to install a libtcc1.a
      but only when cross compiling. And no x86_64 directory.

    * Build/install i386-tcc/x86_64-tcc and not a tcc
    * Build/install i386-win-tcc/x86_64-win-tcc and not a i386-win-mingw32-tcc/...
    * DEFINES = -DTCC_TARGET_I386... also for i386-tcc and i386-win-tcc
    * Make a symlink tcc to the i386-tcc/x86_64-tcc for a "make test"
    * Build a $(ARCH) directory with a symlink to the libtcc1.a for a "make test"
    * Remove a /usr/local/lib/tcc directory on uninstall
    * Remove a /usr/local/share/doc/tcc directory on uninstall
    * Remove a $(ARCH) directory on "make clean"
    * Remove a *-tcc files on "make clean"
2015-03-04 11:40:33 +03:00
seyko
54fc439e9e an unification of the tcc cross names for a windows
produce a
      i386-win-mingw32-tcc
      i386-win-tcc
      x86_64-win-mingw32-tcc
      x86_64-win-tcc
      arm-win-mingw32ce-tcc
      arm-win-tcc

    instead of the
      i386-w64-mingw32-tcc
      i386-win32-tcc
      x86_64-w64-mingw32-tcc
      x86_64-win32-tcc
      arm-wince-mingw32ce-tcc
      arm-win32-tcc

    Replacing a *-win32 directory names with a *-win names
    because this names are based on the names of the tcc
    	x86_64-win32-tcc, i386-win32-tcc
2015-03-04 11:19:39 +03:00
seyko
1cbb4d322b build-libtcc1-by-tcc: use a new tcc to compile a libtcc1.c and alloca.S
This will allow to build a libtcc1.a even if a bootstrap compiler
don't support a target arch.

There was alrady this feature but only for OS Darwin.
2015-03-04 11:08:16 +03:00
seyko
7ed4341538 a libraries paths
* x86_64-tcc: use /usr/lib64,.. instead of /usr/lib,..
    * don't set tcc_lddir="lib64" if cpu="x86"
    * put a definition of the CONFIG_LDDIR into config.h instead
      of the config.mak  Otherwise a "lib" string may be used by default.
      This is a usual case when building a x86_64-tcc (there was
      no -DCONFIG_LDDIR building this binary).

    * suppress -Wdeprecated-declarations for gcc which complain on malloc hooks
      in bcheck.c if glibc is quite new.
2015-03-04 10:57:13 +03:00
seyko
7ec39e2288 reverse a commit a6149c6dbb: Set CONFIG_MULTIARCHDIR for cross compilers.
Set CONFIG_MULTIARCHDIR for cross compilers.
    Chances a cross-compiler will find a working crt*.o
    in /usr/lib are more or less 0.

This commit breaks x86 / x86_64 compilres for linux. A solution for the crt*.o
must be discussed.
must be:
    # ./x86_64-tcc -vv
    tcc version 0.9.26 (x86-64, Linux)
    install: /usr/local/lib/tcc
    crt:
      /usr/lib64
    libraries:
      /usr/lib64
      /lib64
      /usr/local/lib64
    include:
      /usr/local/include
      /usr/include
      /usr/local/lib/tcc/include
    elfinterp:
      /lib64/ld-linux-x86-64.so.2

and with MULTIARCH we have:
    # ./x86_64-tcc -vv
    tcc version 0.9.26 (x86-64 Linux)
    install: /usr/local/lib/tcc/
    crt:
      /usr/lib/x86_64-linux-gnu ???????????????????
    libraries:
      /usr/lib/x86_64-linux-gnu
      /usr/lib                  ???????????????????
      /lib/x86_64-linux-gnu
      /lib                      ???????????????????
      /usr/local/lib/x86_64-linux-gnu
      /usr/local/lib            ???????????????????
    include:
      /usr/local/include/x86_64-linux-gnu
      /usr/local/include
      /usr/include/x86_64-linux-gnu
      /usr/include
      /usr/local/lib/tcc/include
    elfinterp:
      /lib64/ld-linux-x86-64.so.2

And CONFIG_MULTIARCHDIR don't handle C67.
On Linux x86 we have:
    # ./c67-tcc -vv
    tcc version 0.9.26 (C67, Linux)
    install: /usr/local/lib/tcc
    crt:
      /usr/lib
    libraries:
      /usr/lib
      /lib
      /usr/local/lib
    include:
      /usr/local/include
      /usr/include
      /usr/local/lib/tcc/include
    elfinterp:
      /lib/ld-linux.so.2
2015-03-04 10:50:33 +03:00
seyko
149c2a9cc9 a cpu option of the configure script as a method to specify a target cpu
* don't setup a cpu before scanning for --cpu=
    * --cpu= option sets a 'cpu' variable, not a 'build_cpu', 'build_cpu' was not used anywhere.
    * if cpu="" and ARCH != "" then cpu=$ARCH else cpu=`uname -m`
    * replace "Build CPU" with "Target CPU" in the output of the configure script.
      output this value only when not builing a cross compilers.
    * remove a HOST_I386, ... defines from a config.h file.
      thise defines are not used anywhere and cpu is now used to define a target cpu
2015-03-04 10:03:40 +03:00
seyko
d972472c53 Disable floating-point test for ARM soft-float
From: Matteo Cypriani <mcy@lm7.fr>
    Date: Fri, 5 Sep 2014 23:22:56 -0400
    Subject: Disable floating-point test for ARM soft-float

    tcc is not yet capable of doing softfloat floating-point operations on
    ARM, therefore we disable this test for these platforms. Note that tcc
    displays a warning to warn ARM users about this limitation
    (debian)
2015-03-04 09:52:47 +03:00
seyko
f1e4b2b7f3 disable-BTESTS 2015-03-04 09:49:19 +03:00
seyko
b8925960ec correct a DllMain() declaration in dllcrt1.c and dllmain.c
There is a DllMain() declaration in the mingw-runtime-4.0.3.1
and it differs from a tcc one.
2015-03-03 22:51:13 +03:00
seyko
7b96ddd045 win32/include/winsock2.h (look previous commit) 2015-03-03 22:45:50 +03:00
seyko
351e2ec334 add declaration of the "double trunc (double _x)" and winsock2.h
This allow to build a windows version of the nimrod compiler.
2015-03-03 22:41:55 +03:00
seyko
4b61f7f04b A lrint functions in win32/include/math.h are rewrittem because tcc can't handle "t" constraint 2015-03-03 22:38:31 +03:00
seyko
dfbb00c106 wincrt1.c: add definition of the __TRY__ if not defined
Some i686-pc-mingw32-gcc don't know about __TRY__
2015-03-03 22:35:33 +03:00
seyko
859ce5e47f Report a mingw as a execution environment instead of the
Win32, Win64, WinCE when executing "tcc -v". Example
	$ ./i386-win-tcc -v
	tcc version 0.9.26 (i386, mingw)
instead of the
	tcc version 0.9.26 (i386, Win32)

There is a cpu info already about bits of the excution environment
And display C67 for the TCC_TARGET_C67
2015-03-03 22:30:24 +03:00
seyko
2e6626a4b3 Don't add a slash to the install path of the tcc in display_info() 2015-03-03 21:41:22 +03:00
seyko
d70440b406 A 32/64 bit tcc on linux: an arch specific path for libtcc1.a
Don't use /usr/local/lib/tcc/libtcc1.a for i386 and x86_64
A $(tccdir)/i386 directory was used to install a libtcc1.a
but only when cross compiling. And no x86_64 directory.
And this directory location was unknown inside tccelf.c
2015-03-03 18:34:22 +03:00
seyko
43e4a406b4 Disable floating-point test for ARM soft-float
From: Matteo Cypriani <mcy@lm7.fr>
    Date: Fri, 5 Sep 2014 23:22:56 -0400
    Subject: Disable floating-point test for ARM soft-float

    tcc is not yet capable of doing softfloat floating-point operations on
    ARM, therefore we disable this test for these platforms. Note that tcc
    displays a warning to warn ARM users about this limitation
    (debian)
2015-03-03 17:28:13 +03:00
seyko
774f0611cc arm-unused-warnings: remove problems with defined but unused wariables
arm-gen.c: In function `gfunc_call':
	arm-gen.c:1202: warning: unused variable `variadic'
	arm-gen.c: In function `gfunc_prolog':
	arm-gen.c:1258: warning: unused variable `avregs'
	arm-gen.c:1340: warning: label `from_stack' defined but not used
	arm-gen.c:222: warning: 'default_elfinterp' defined but not used
2015-03-03 17:16:52 +03:00
seyko
6cbf4fb740 tcc_add_runtime() for a CONFIG_USE_LIBGCC case: reducing a complexity 2015-03-03 17:11:18 +03:00
seyko
cd4f3d962d x86_64-win-tcc elfinterp: a bug correction
./x86_64-win-tcc -vv
Before
	elfinterp:
	  /lib64/ld-linux-x86-64.so.2
After
	elfinterp:
	  -
This output is identical to the output of the i386-win-tcc
2015-03-03 17:05:44 +03:00
seyko
2d83ec7aa3 lddir-on-x86-64: let CONFIG_LDDIR=lib64 by default if TCC_TARGET_X86_64
This is done for the case when CONFIG_LDDIR is not configured. Example:
./configure --enable-cross
2015-03-03 16:37:44 +03:00
seyko
b5f88b593a Turn on a implicit-function-declaration warning by default.
A non declared function leads to a seriuos problems. And while
gcc don't turn this warning on lets tcc do it. This warning
can be turned off by -Wno-implicit-function-declaration option.
And autor must explicitly do this if program must be compiled
with this warning off.
2015-03-03 16:32:25 +03:00
seyko
7f36abd3f2 x86_64-tcc and libtcc1.c: size_t definition is needed for a x86_64-tcc to parse memset() 2015-03-03 16:29:00 +03:00
seyko
e374a733d6 -std=c99 option for the tcc: allow to use a tcc as a reference compiler for "make test"
tcc will igmore this option.
2015-03-03 16:25:02 +03:00
seyko
4c8ffb353d remove a gcc warning for bcheck on x86_64 arch: conversion to pointer from integer of different size 2015-03-03 16:18:24 +03:00
seyko
20074d8862 Use a display_info() to output a header of the tcc help listing
tcc version 0.9.26 (i386 Linux)
    Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard
    Usage: tcc [options...] [-o outfile] [-c] infile(s)...
	   tcc [options...] -run infile [arguments...]
    ...

instead of the

    tcc version 0.9.26 - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard
    Usage: tcc [options...] [-o outfile] [-c] infile(s)...
	   tcc [options...] -run infile [arguments...]
    ...

Displaing a "Hard Float" info for the ARM arch is restored. It was broken by the AArm64 patch.
2015-03-03 16:08:33 +03:00
seyko
2437ccdc76 A partial reverse for commit eda2c756ed
Author: Thomas Preud'homme <robotux@celest.fr>
	Date:   Tue Dec 31 23:51:20 2013 +0800

	Move logic for if (int value) to tccgen.c
	Move the logic to do a test of an integer value (ex if (0)) out of
	arch-specific code to tccgen.c to avoid code duplication. This also
        fixes test of long long value which was only testing the bottom half of
	such values on 32 bits architectures.

I don't understand why if () in gtst(i) was removed.
This patch allows to compile a linux kernel v.2.4.26
W/o this patch a tcc simply crashes.
2015-03-03 15:51:09 +03:00
seyko
c45a8695eb A reverse of the commit 14745bdeb because of the problems while compiling linux 2.4.26
A test program:
    ///////////
    typedef unsigned int __u32;
    static inline const __u32 __fswab32(__u32 x)
    {
	return ({ __u32 __tmp = (x) ; ___swab32(__tmp); });
    }
    void func()
    {
	int aaa = 1;
	int snd_wnd = 2;
	int TCP_FLAG_ACK = 3;
	int pred_flags = (__builtin_constant_p((__u32)
	    (((aaa << 26) |
	    (__builtin_constant_p((__u32)((TCP_FLAG_ACK))) ?
		({ __u32 __x = (((TCP_FLAG_ACK))); ((__u32)( (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); }) : __fswab32(((TCP_FLAG_ACK)))) | snd_wnd))) ? ({ __u32 __x = ((((aaa << 26) | (__builtin_constant_p((__u32)((TCP_FLAG_ACK))) ? ({ __u32 __x = (((TCP_FLAG_ACK))); ((__u32)( (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); }) : __fswab32(((TCP_FLAG_ACK)))) | snd_wnd))); ((__u32)( (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); }) : __fswab32((((aaa << 26) | (__builtin_constant_p((__u32)((TCP_FLAG_ACK))) ? ({ __u32 __x = (((TCP_FLAG_ACK))); ((__u32)( (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); })
		: __fswab32(((TCP_FLAG_ACK)))) | snd_wnd))));
    }
    ////////////
error: ';' expected (got "(")
2015-03-03 15:44:29 +03:00
seyko
6fd4e5bace a void to void cast.
Allow tcc to compile the following program
    ///////
	void func1() {}
	void func2() {
	  return func1();
	}
    //////
gcc accepts this program
2015-03-03 15:39:57 +03:00
seyko
09feeca5df a statement expressions with a pointer return type
A test program:
    //////////////
    int main()
    {
	void *p = ({ 0 ; ((void *)1); });
    }
    /////////////
Porblem is introduced in a commit a80acab: Display error on statement expressions with complex return type
This error is exposed when compiling a linux 2.4.26. tcc 0.9.23 can sucessfully compile
this version of the linux.
2015-03-03 15:29:14 +03:00
seyko
1a1e9548fb iitialisation of the empty struct
Current tcc don't understand an initialization of the empty struct
This problem was found trying to compile a linux kernel 2.4.26
which can be compiled by tcc 0.9.23

  A test program:
  ////////////////////
  // ./tcc -c test_3.c
  // test_3.c:31: error: too many field init
  #undef __GNUC__
  #undef __GNUC_MINOR__
  #define __GNUC__  2
  #define __GNUC_MINOR__ 95
  typedef struct { } rwlock_t;
  struct fs_struct {
   int count;
   rwlock_t lock;
   int umask;
  };
  #define INIT_FS { \
	1, \
	RW_LOCK_UNLOCKED, \
	0022, \
  }
  #if (__GNUC__ > 2 || __GNUC_MINOR__ > 91)
    typedef struct { } rwlock_t;
    #define RW_LOCK_UNLOCKED (rwlock_t) { }
  #else
    typedef struct { int gcc_is_buggy; } rwlock_t;
    #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
  #endif
  static struct fs_struct init_fs = INIT_FS;
  // static struct fs_struct init_fs = { { (1) }, (rwlock_t) { 0 }, 0022, };
  //                                                           ^ with this all Ok
  // static struct fs_struct init_fs = { { (1) }, (rwlock_t) { }, 0022, };
  //                                                          ^ current tcc don't understand, but tcc 0.9.23 can
  int main()
  {
    return 0;
  }
  ////////////////////
  A regression is detected after a patch 69fdb57edd
  ////////////////////
  // A test for patch 69fdb57edd
  // Author: grischka <grischka>
  // Date:   Wed Jun 17 02:09:07 2009 +0200
  //     unions: initzialize only one field
  //         struct {
  //           union {
  //             int a,b;
  //           };
  //           int c;
  //         } sss = { 1,2 };
  //     This had previously assigned 1,2 to a,b and 0 to c which is wrong.
  //
  // Expected: sss.a=1 sss.b=1 sss.c=2
  int main()
  {
    struct {
      union {
        int a,b;
      };
      int c;
    } sss = { 1, 2 };

    printf ("sss.a=%d sss.b=%d sss.c=%d\n", sss.a, sss.b, sss.c);
    return 0;
  }
  ////////////////////
2015-03-03 15:15:48 +03:00
seyko
bbf8221ec3 tcc don't understand am extern array of structs.
A regression was found trying to compile a linux kernel 2.4.26
  which can be compiled by tcc 0.9.23

    ///////////////////
    #include <stdio.h>

    // test for a bug:
    // compiler don't understand am extern array of structs
    // $ tcc test_1.c
    // test_1.c:8: error: unknown struct/union/enum

    extern struct FILE std_files[4];

    int main()
    {
	return 0;
    }
    //////////////////

  tcc-current
  /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
  static void struct_decl(CType *type, int u, int tdef)
  ...
    if (tok != '{') {
        v = tok;
        next();
        /* struct already defined ? return it */
        if (v < TOK_IDENT)
            expect("struct/union/enum name");
        s = struct_find(v);
        if (s) {
            if (s->type.t != a)
                tcc_error("invalid type");
            goto do_decl;
        } else if (tok >= TOK_IDENT && !tdef)
            tcc_error("unknown struct/union/enum");
    } else {
        v = anon_sym++;
    }

  tcc-0.9.23 which don't have such error
  /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
  static void struct_decl(CType *type, int u)
  ....
    if (tok != '{') {
        v = tok;
        next();
        /* struct already defined ? return it */
        if (v < TOK_IDENT)
            expect("struct/union/enum name");
        s = struct_find(v);
        if (s) {
            if (s->type.t != a)
                error("invalid type");
            goto do_decl;
        }
    } else {
        v = anon_sym++;
    }
2015-03-03 15:00:13 +03:00
seyko
a429d40f06 tcc_free(table_ident) in preprocess_new() if table_ident != NULL 2015-03-03 14:54:46 +03:00
seyko
e2a8fd4520 tcc_undefine_symbol(): free an alloced symbol 2015-03-03 14:50:41 +03:00
seyko
8d10c5788f Add a debug info when a #line directive is handled.
The problem was: a debug info for the file which contain a #line
directive (for example a preprocessed one) was wrong.
2015-03-03 14:46:44 +03:00
seyko
09d4e4f408 Revert a grischka patch: gdb refused to know "main"
It is a strange patch because before this commit a gdb is working well
and after this commit there is exactly the same problem on Linux:
gdb refuses to know "main"

    Author: grischka <grischka>
    Date:   Tue Feb 5 21:18:29 2013 +0100
    tccelf: fix debug section relocation
    With:
       tcc -g hello.c
       gdb a.out
         b main
    gdb refused to know "main" because of broken dwarf info.
2015-03-03 14:39:27 +03:00
seyko
252a151fc6 pp-many-files: don't drop a preprocessor defines when tcc going to preprocess a next file
in the same pass like
    tcc -E one.c two.c three.c -o combined.i
This will allow to speed up a compilation process by using a commamd like
    tcc -E *.c | tcc -o program.exe -xc -

It looks that multi-times initialization don't affect anything.
Only call to the free_defines(define_start) in tcc_preprocess()
is removed in assumption that free_defines(NULL) in
tcc_cleanup() will free all defines.
2015-03-03 14:31:47 +03:00
seyko
b7b9f9f511 A gcc preprocessor option -dD added
With this option on a defines are included into the output
(inside comments). This will allow to debug a problems like:

    In file included from math.c:8:
    In file included from /usr/include/math.h:43:
    /usr/include/bits/nan.h:52: warning: NAN redefined
2015-03-03 14:25:57 +03:00
seyko
50cdccf3ef Added a gcc preprocessor options -P, -P1
tcc -E -P
  do not output a #line directive, a gcc compatible option

tcc -E -P1
  don't follow a gcc preprocessor style and do output a standard
  #line directive. In such case we don't lose a location info when
  we going to compile a resulting file wtith a compiler not
  understanding a gnu style line info.
2015-03-03 14:19:14 +03:00
seyko
40418f87c7 Move a line_ref variable from tcc_preprocess() function into struct BufferedFile.
This id needed for a right ouput in other places,
precisely to calculate a number of empty lines which are waiting to output.
2015-03-03 14:15:28 +03:00
seyko
5e3e321474 A preprocessor should Interpret an input line "# NUM FILENAME" as "#line NUM FILENAME"
A cpp from gcc do this.
A test case:
     tcc -E tccasm.c -o tccasm.i
     tcc -E tccasm.i -o tccasm.ii
After a patch the line numbers in tccasm.ii are the same
as in tccasm.i
2015-03-03 14:06:05 +03:00
Edmund Grimley Evans
1706d2254b arm64-gen.c: Improve generation of stack offsets. 2015-03-02 20:51:03 +00:00
Edmund Grimley Evans
1d41da9590 arm64-gen.c: Rename some functions and add comments. 2015-03-02 20:45:58 +00:00
Edmund Grimley Evans
86e8dcd5e2 arm64: Improve constant generation, with tests. 2015-03-02 20:39:28 +00:00
Edmund Grimley Evans
883fd365c7 arm64-gen.c: Better explanation of relocation choice. 2015-03-01 11:31:10 +00:00
Edmund Grimley Evans
fc119f9840 73_arm64.c: Avoid taking address of return value. 2015-02-26 12:27:00 +00:00
Edmund Grimley Evans
8329facdfa Add 73_arm64 for testing some arm64 things, mostly PCS. 2015-02-25 22:51:41 +00:00
Edmund Grimley Evans
a4d43618fb arm64-gen.c: In gen_va_arg, handle the remaining HFA cases. 2015-02-25 22:51:41 +00:00
Edmund Grimley Evans
36bb8994dd Relicensing TinyCC 2015-02-25 07:52:39 +00:00
Edmund Grimley Evans
97e08be344 tests/tcctest.c: Test COMPAT_TYPE(char *, signed char *). 2015-02-24 19:35:31 +00:00
Edmund Grimley Evans
40f7e11c53 tccgen.c: Make sure that gen_op always returns an rvalue.
Either this fix, or an alternative one, is required for arm64.
2015-02-23 22:51:10 +00:00
Michael Matz
6d055312a2 aarch64: Fix -run.
This adds some more support for properly transfering some
offsets over the different stages of a relocations life.
Still not at all psABI compliant and DSOs can't yet be generated.
But it runs the testsuite in qemu-arm64.
2015-02-23 22:51:10 +00:00
Edmund Grimley Evans
b14ef0e24b Add arm64 (AArch64) as a target architecture. 2015-02-23 22:51:03 +00:00
Edmund Grimley Evans
738606dbd5 Use RELA relocations properly for R_DATA_PTR on x86_64.
libtcc.c: Add greloca, a generalisation of greloc that takes an addend.
tcc.h: Add greloca and put_elf_reloca.
tccelf.c: Add put_elf_reloca, a generalisation of put_elf_reloc.
tccgen.c: On x86_64, use greloca instead of greloc in init_putv.
2015-02-21 21:29:03 +00:00
Edmund Grimley Evans
86c850fc58 tcc-doc.texi: Explain VT_LLOCAL a bit better.
And delete the sentence about it being removed.
2015-02-20 23:29:21 +00:00
Edmund Grimley Evans
ff3f9aa6ba Fix handling of case_reg in switch statement.
The back end functions gen_op(comparison) and gtst() might allocate
registers so case_reg should be left on the value stack while they
are called and set again afterwards.
2015-02-20 23:16:00 +00:00
Thomas Preud'homme
a6c3ce6ec0 The "open a whisky and cut your finger open" patch
Make integer constant parsing C99 compliant
2015-02-18 07:01:03 +00:00
Reimar Döffinger
ff783b94c7 Add support for .p2align asm directive.
Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
2015-01-20 08:49:49 +01:00
Reimar Döffinger
fb6331e0fa Fix macro expansion of empty args.
Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
2015-01-18 22:00:10 +01:00
Reimar Döffinger
a6149c6dbb Set CONFIG_MULTIARCHDIR for cross compilers.
Chances a cross-compiler will find a working crt*.o
in /usr/lib are more or less 0.

Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
2015-01-18 21:21:59 +01:00
Reimar Döffinger
ae09558d71 Build also WinCE cross compiler when cross compilers enabled.
Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
2015-01-18 21:16:34 +01:00
seyko
e260b03686 Allow tcc to understand a setob,... opcodes as alias to seto,...
PS: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20101122/112576.html
This is fix PR8686 for llvm: accepting a 'b' suffix at the end
of all the setcc instructions.
2015-01-06 22:59:19 +03:00
seyko
c334b59142 Warn about a conflicting compile options spectified on the command line.
Try "tcc -E -c tccasm.c -o tccasm.o"
2015-01-06 22:19:45 +03:00
seyko
b93179f3c0 .i as file extension
Add a ".i" extension as alias for ".c"
 GCC and file extensions:
 .i C source code which should not be preprocessed.

Before a patch:
 ./tcc -E tccasm.c -o tccasm.i
 ./tcc -c tccasm.i -o tccasm.o
 tccasm.i:1: error: unrecognized file type
2015-01-06 16:01:41 +03:00
seyko
524abd46b4 round() in test (24_math_library) fail because there are no defs included.
gcc complain but work right and tcc simply fail to compile right.
2015-01-05 18:23:32 +03:00
Carlos Montiers
77ef3b2929 crt1.c revision 2014-12-30 00:25:52 -03:00
Lee Duhem
5a76c5d2f3 Fix parsing of binary floating point number
* tccpp.c (parse_number): `shift' should be 1 while parsing binary
floating point number.
* tests/tests2/70_floating_point_literals.c: New test cases for
floating point number parsing.
2014-12-15 16:32:08 +08:00
Lee Duhem
20a5845a47 tcc.h (BufferedFile): Remove unnecessary static memory allocation
The memory needed by `buffer' will be allocated in `tcc_open_bf',
these is no need to allocate them in BufferedFile statically.
2014-12-11 10:04:22 +08:00
Lee Duhem
f1703e2b2f libtcc.c (put_extern_sym2): Extend the scope of buf to match its use
After leaving the code block that `buf' is defined, `buf' will not
exist, so `name' will point to a variable that does not exist.
2014-12-11 10:04:22 +08:00
Lee Duhem
4bf3f6c965 .gitignore: Ignore Emacs temporary files 2014-12-11 10:04:22 +08:00
Lee Duhem
73e8f6b60a Makefile: Add rules to create tags and TAGS. 2014-11-28 23:25:05 +08:00
Lee Duhem
4ae462b668 .gitignore: Ignore generated files. 2014-11-28 23:24:55 +08:00
Carlos Montiers
9b14e8715a little optimization to crt1 2014-11-23 01:51:38 -03:00
Carlos Montiers
f40b82295e __getmainargs compatibility checking success 2014-11-22 19:00:49 -03:00
James Buren
1e07ea71d3 win32: fix implicit function warning
This includes windows.h to fix a warning about
an implicit function usage of ExitProcess().
2014-11-03 16:17:15 -06:00
Matteo Cypriani
26b26f355f Filter-out warning about softfloat in tests2 2014-10-17 16:37:54 -04:00
grischka
9d7fb33360 tccgen: use lvalue as result from bitfield assignment
test case:

    #include <stdio.h>
    int main(int argc, char **argv)
    {
        struct _s { unsigned a:9, b:5, c:7; } _s, *s = &_s;
        int n = 250;
        s->a = s->b = s->c = n + 4;
        printf("--> %d / %d / %d\n", s->a, s->b, s->c);
        return 0;
    }

before:
--> 254 / 30 / 126
now:
--> 30 / 30 / 126
2014-09-23 12:30:08 +02:00
Matteo Cypriani
87d879aa7b Accept CPPFLAGS from the environment
Don't override CPPFLAGS so that it can be passed through the
environment.

(This is a patch Thomas Preud'homme wrote for Debian in February 2013.)
2014-09-07 12:07:04 -04:00
Matteo Cypriani
63376d7712 tccelf: layout_sections: add missing param strsec
This fixes compilation on (k)FreeBSD.
2014-09-07 12:04:53 -04:00
Matteo Cypriani
b84cdf6214 Clear CFLAGS & LDFLAGS in tests
Clear CFLAGS and LDFLAGS to build the tests, in case the main Makefile
passes some flags that aren't handled by tcc (we are not compiling tcc
here, we are using tcc to compile the tests).
2014-09-07 11:15:31 -04:00
Matteo Cypriani
178275dc0c Don't build libtcc1 with -fstack-protector-strong
Prevent libtcc1.a to be compiled with -fstack-protector-strong, so that
linking with tcc doesn't fail because symbol '__stack_chk_fail_local' is
not present in libtcc1.a. This is useful only if the CFLAGS passed from
the main Makefile contain this flag.
2014-09-07 10:56:03 -04:00
grischka
14745bdeb7 tccgen: nocode_wanted: do not output constants
This for example suppresses string constants such as with

    int main()
    {
        return sizeof "foo";
    }

Actually, setting

    nocode_wanted = 1;

in libtcc.c for the initial global level seemed wrong, since
obviously "nocode_wanted" means code as any side effects, also
such as string constants.

This reverts a part of 2de1b2d14c
(documented as "Some in-between fixes" in Changelog)
2014-08-01 10:59:38 +02:00
grischka
12f43953ed win64: fix resource file support 2014-08-01 10:51:28 +02:00
Carlos Montiers
73a7dd79af Removed the error message and minor changes. 2014-07-17 01:08:47 -04:00
Carlos Montiers
7c474b4da3 __getmainargs return int, not void, and on error, it return -1 and let argv untouched, also argc. Added a if checking the result of it. 2014-07-16 22:22:05 -04:00
Carlos Montiers
f2ee6b1759 Fix mistake. Change jb by jbe. tiny c round (INT_MAX = 0x7FFFFFFF) to a DWORD boundary and it becomes 0x80000000. Jle treats as -214783648, but Jbe treats as 214783648. Thanks to Jason Hood for explain me this. 2014-07-10 20:41:51 -04:00
Carlos Montiers
8257829623 Fix problem using alloca function, executable crashed even with a exception handler function, when try to allocate INT_MAX. Patch provided by Jason Hood in private e-mail, when I ask to him for help. He say: Feel free to pass it on to the mailing list. 2014-07-10 00:37:20 -04:00
jiang
89000c18dc Rename:
68_macro_concat.c -> 68_macro_param_list_err_1.c
69_macro_concat.c -> 69_macro_param_list_err_2.c
and Remove spaces
2014-07-01 23:54:49 +08:00
Thomas Preud'homme
b31e80a43a Specify license of lib/armeabi.c 2014-07-01 22:01:49 +08:00
jiang
a3fc543459 bug:
----------------------------------------------------------------------
#define hexCh(c (c >= 10 ? 'a' + c - 10 : '0' + c)
  hexCh(c);

out:
jiang@jiang:~/test$ ./tcc -E c4.c
# 1 "c4.c"

(c >= 10 ? 'a' + c - 10 : '0' + c);
---------------------------------------------------------------

#define hexCh(c/3) (c >= 10 ? 'a' + c - 10 : '0' + c)
hexCh(c);

out:
jiang@jiang:~/test$ ./tcc -E c4.c
# 1 "c4.c"

/3) (c >= 10 ? 'a' + c - 10 : '0' + c);
jiang@jiang:~/test$

after patch:

# 1 "c4.c"
c4.c:1: error: may not appear in macro parameter list: "("
jiang@jiang:~/test$

jiang@jiang:~/test$ ./tcc -E c4.c
# 1 "c4.c"
c4.c:1: error: may not appear in macro parameter list: "/"
jiang@jiang:~/test$
2014-06-29 20:35:57 +08:00
David Mertens
799512388c Revert the many un-reviewed commits starting from early April
Starting early April, a number of commits were pushed to the mob branch
that did not reflect the interest, wishes, or code quality of the tcc
community. This commit reverts those commits, while cherry-picking
grishka's commit for win64 linkage issues.
2014-06-24 22:42:57 -04:00
grischka
6e0a658e96 win64: try to fix linkage
- revert to R_X86_64_PC32 for near calls on PE
- revert to s1->section_align set to zero by default

Untested. Compared to release_0_9_26 the pe-image looks back to
normal.  There are some differences in dissassembly (r10/r11 usage)
but maybe that's ok.
2014-06-24 22:09:12 -04:00
jiang
f26fdaefd8 revert vstore() 2014-06-23 01:08:54 +08:00
Thomas Coudray
1fa0fe2786 Revert "Win: Enable use "*.def + *.c" files as library instead of *.a by "-l" option"
This reverts commit 7a3f6d4941.
2014-06-20 13:26:29 +01:00
YX Hao
7a3f6d4941 Win: Enable use "*.def + *.c" files as library instead of *.a by "-l" option
example: "-lshell32" will try "shell32.def + shell32.c"

Add lib type "%s/%s.c" for tcc_add_library() ('-l' option parse)

So tcc can use all files as scripts.
2014-06-16 16:00:46 +08:00
jiang
d316836008 Let init_putz one-time generation.
At the same time, increase the GCC style warning
---------------------------------------------------------------------------
int main()
{
	int a[10] = {[5]=5};
	return 0;
}

Disassembly of section .text:

0000000000000000 <main>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	48 81 ec 30 00 00 00 	sub    $0x30,%rsp
   b:	b8 05 00 00 00       	mov    $0x5,%eax
  10:	89 45 ec             	mov    %eax,-0x14(%rbp)
  13:	48 b8 14 00 00 00 00 	movabs $0x14,%rax
  1a:	00 00 00
  1d:	49 89 c2             	mov    %rax,%r10
  20:	b8 00 00 00 00       	mov    $0x0,%eax
  25:	48 89 c6             	mov    %rax,%rsi
  28:	48 8d 45 d8          	lea    -0x28(%rbp),%rax
  2c:	48 89 c7             	mov    %rax,%rdi
  2f:	4c 89 d2             	mov    %r10,%rdx
  32:	b8 00 00 00 00       	mov    $0x0,%eax
  37:	e8 fc ff ff ff       	callq  38 <main+0x38>
  3c:	48 b8 10 00 00 00 00 	movabs $0x10,%rax
  43:	00 00 00
  46:	49 89 c2             	mov    %rax,%r10
  49:	b8 00 00 00 00       	mov    $0x0,%eax
  4e:	48 89 c6             	mov    %rax,%rsi
  51:	48 8d 45 f0          	lea    -0x10(%rbp),%rax
  55:	48 89 c7             	mov    %rax,%rdi
  58:	4c 89 d2             	mov    %r10,%rdx
  5b:	b8 00 00 00 00       	mov    $0x0,%eax
  60:	e8 fc ff ff ff       	callq  61 <main+0x61>
  65:	b8 00 00 00 00       	mov    $0x0,%eax
  6a:	e9 00 00 00 00       	jmpq   6f <main+0x6f>
  6f:	c9                   	leaveq
  70:	c3                   	retq

After the patch

0000000000000000 <main>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	48 81 ec 30 00 00 00 	sub    $0x30,%rsp
   b:	48 b8 28 00 00 00 00 	movabs $0x28,%rax
  12:	00 00 00
  15:	49 89 c2             	mov    %rax,%r10
  18:	b8 00 00 00 00       	mov    $0x0,%eax
  1d:	48 89 c6             	mov    %rax,%rsi
  20:	48 8d 45 d8          	lea    -0x28(%rbp),%rax
  24:	48 89 c7             	mov    %rax,%rdi
  27:	4c 89 d2             	mov    %r10,%rdx
  2a:	b8 00 00 00 00       	mov    $0x0,%eax
  2f:	e8 fc ff ff ff       	callq  30 <main+0x30>
  34:	b8 05 00 00 00       	mov    $0x5,%eax
  39:	89 45 ec             	mov    %eax,-0x14(%rbp)
  3c:	b8 00 00 00 00       	mov    $0x0,%eax
  41:	e9 00 00 00 00       	jmpq   46 <main+0x46>
  46:	c9                   	leaveq
  47:	c3                   	retq
 -----------------------------------------------------------------------------------
"c5.c"
int main()
{
  // union st
   struct st
   {
    char c;
    short s;
   // char cc[];
    };
   // union st
  struct st
    ss = { 1, 2, 3};
   // int a = ss;
    char cb[1] = {1,2,3};
    return 0;
}

c5.c:12: warning: excess elements in struct initializer
c5.c:14: warning: excess elements in array initializer
c5.c:14: warning: excess elements in array initializer
2014-05-28 22:09:49 +08:00
jiang
89134dd7b0 Considering the effect of CH_EOF on line_num 2014-05-28 21:51:50 +08:00
jiang
698b16960a Modify the 66_macro_concat_end.expect
I was busy recently, forget test. Thank Austin
2014-05-28 10:38:26 +08:00
jiang
bcf60562e0 The number of rows to display warning is wrong
For example:
#define TOK_ASM_weak TOK_WEAK1
#define TOK_ASM_weak TOK_WEAK
Output:
C8.c:3: warning: TOK_ASM_weak redefined
2014-05-23 15:46:08 +08:00
jiang
9c78da8a32 forget Delete __va_ld_reg 2014-05-21 12:50:12 +08:00
jiang
3d608d4b54 Delete a = (a > = 0)? A: -a; \ 2014-05-20 15:23:55 +08:00
jiang
0199123dd7 clean '\t' 2014-05-20 15:18:59 +08:00
jiang
f8b4f59f8b In the local use of local stack, use a global stack in the global time 2014-05-20 14:59:37 +08:00
jiang
e5e7f488e2 int main()
{
	struct st {
		int aa:16;
		int bb:16;
	} s;
	s.aa = 1;
	s.bb = 2;
	return 0;
}
objdump -d:
elf64-x86-64
Disassembly of section .text:

0000000000000000 <main>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	48 81 ec 10 00 00 00 	sub    $0x10,%rsp
   b:	b8 01 00 00 00       	mov    $0x1,%eax
  10:	48 89 c1             	mov    %rax,%rcx
  13:	81 e1 ff ff 00 00    	and    $0xffff,%ecx
  19:	8b 55 fc             	mov    -0x4(%rbp),%edx
  1c:	81 e2 00 00 ff ff    	and    $0xffff0000,%edx
  22:	09 d1                	or     %edx,%ecx
  24:	89 4d fc             	mov    %ecx,-0x4(%rbp)
  27:	b8 02 00 00 00       	mov    $0x2,%eax
  2c:	48 89 c1             	mov    %rax,%rcx
  2f:	81 e1 ff ff 00 00    	and    $0xffff,%ecx
  35:	c1 e1 10             	shl    $0x10,%ecx
  38:	8b 55 fc             	mov    -0x4(%rbp),%edx
  3b:	81 e2 ff ff 00 00    	and    $0xffff,%edx
  41:	09 d1                	or     %edx,%ecx
  43:	89 4d fc             	mov    %ecx,-0x4(%rbp)
  46:	b8 00 00 00 00       	mov    $0x0,%eax
  4b:	e9 00 00 00 00       	jmpq   50 <main+0x50>
  50:	c9                   	leaveq
  51:	c3                   	retq

After the patch

Disassembly of section .text:

0000000000000000 <main>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	48 81 ec 10 00 00 00 	sub    $0x10,%rsp
   b:	8b 45 fc             	mov    -0x4(%rbp),%eax
   e:	81 e0 00 00 ff ff    	and    $0xffff0000,%eax
  14:	83 c8 01             	or     $0x1,%eax
  17:	89 45 fc             	mov    %eax,-0x4(%rbp)
  1a:	8b 45 fc             	mov    -0x4(%rbp),%eax
  1d:	81 e0 ff ff 00 00    	and    $0xffff,%eax
  23:	81 c8 00 00 02 00    	or     $0x20000,%eax
  29:	89 45 fc             	mov    %eax,-0x4(%rbp)
  2c:	b8 00 00 00 00       	mov    $0x0,%eax
  31:	e9 00 00 00 00       	jmpq   36 <main+0x36>
  36:	c9                   	leaveq
  37:	c3                   	retq
2014-05-17 12:32:00 +08:00
jiang
a94ed43094 Improved '\ n' output effect (# pragma pack (push, 8), # pragma pack (pop)) 2014-05-17 12:06:18 +08:00
jiang
196c999515 1 macro_push and macro_pop work I made a mistake, no matter the definition does not define can be macro_push.
And the modified tcctest.c test
2, pack: in the compiler under the mode of s1->ppfp, I have no clear ideas1->ppfp
Some advice thank you Roy to me.This patch, I hope I can pass the Roy test
2014-05-17 00:55:02 +08:00
jiang
276553c6b2 add push_macro test again 2014-05-16 15:44:51 +08:00
jiang
52891b6ff6 fix push_macro, asked Tom to help me testfix push_macro 2014-05-16 12:15:00 +08:00
jiang
5a514107c4 When tcc.exe update, abitest-tcc.exe not updated. For security, you must first clean up 2014-05-15 12:09:43 +08:00
jiang
5d0785d0e1 Add warning 4
num en{a1,a2,a3};
enum en ee;
ee = 0xffffffffff;
    char a;
    a = 0xffff;
2014-05-14 21:01:00 +08:00
jiang
fcb3772a34 Add warning 3
struct st {int a;} ss;
int b;
b = ss;
2014-05-14 20:44:53 +08:00
jiang
07614b5e22 clean '\t' 2014-05-14 12:45:58 +08:00
jiang
c6345b5a8a restore 2dd8587c2f32d17a2cd0443a60a614a3fa9bbe29 2014-05-13 22:05:38 +08:00
jiang
72f466c24c Modify tcc_error ("invalid type",); 2014-05-13 22:00:42 +08:00
jiang
8d5e0cf083 fix 14d0aa450f 2014-05-13 21:57:35 +08:00
jiang
03687729ec Add warning 2
For example:
struct A {
int b: 16;
int c: 16
};
sizeof (struct A);
2014-05-09 22:41:45 +08:00
jiang
14d0aa450f Add warning
For example:
struct A {
int b [];
};
2014-05-09 22:35:19 +08:00
grischka
0f51ccd4e4 win64: try to fix linkage
- revert to R_X86_64_PC32 for near calls on PE
- revert to s1->section_align set to zero by default

Untested. Compared to release_0_9_26 the pe-image looks back to
normal.  There are some differences in dissassembly (r10/r11 usage)
but maybe that's ok.
2014-05-08 17:32:29 +02:00
jiang
ad787abea6 fix bug if (seen_reg_num + reg_count <= 8) 2014-05-08 15:39:50 +08:00
grischka
899d26605c Revert "update static void parse_number()"
because:
- Constructing fp numbers isn't quite trivial
- 3 additional calls to strchr per number is noticeable slow

Also: exclude abitest.c:ret_longdouble_test2 on _WIN32
for mixed gcc/tcc scenario

test case:
- make -k test (on win32):
  -2.120000 0.500000 23000000000.000000
  +2.120000 0.500000 22999999999.999996
  ...
  ret_longdouble_test2... failure

This reverts 857f7dbfa6
and deaee6c249
2014-05-06 18:24:41 +02:00
jiang
5e56fb635a Return to: e20c1eb99e
1: The new patch for the other machines still have the problem.
2: libcrt Rename (what if gcc had libcrt as well)
3: parse_number exact problem
4: VT_VLS is to allow tcc
     Compile the following
     int b = 9;
     struct st {
     int a;
     int b [b]
     };
     struct st st1;
     st1.b [8] = 9;
     printf ("% d \ n", st1.b [8]);

     tcc a problem. Due to problems in front, and now can not be improved
5: they commit much, bug difficult to lock, you can not let other people help develop.
6: ('\ t') too

Thanks to Michael and Ray
Their criticism I have benefited!
2014-05-04 13:18:31 +08:00
jiang
089dea355a tcc on i386 are still having problems at work.Thank Roy report again. Struck on several variables can be connected to commit in the register. I am worried whether tcc can run the os. Since my machine is ubuntu 64 bits I can test my machine. 2014-05-03 23:51:09 +08:00
jiang
a0d45c1bcd forget commit tccge.c for i386 2014-05-03 00:39:40 +08:00
jiang
6755b4a3de Modify i386-gen.c,
Thank Roy Tam reported problems
2014-05-03 00:33:19 +08:00
jiang
e647c3137d Fix x86-64 vla
For example, it should look like this
High stack
-------------
----- Func_ret_sub
------------
---- Vla stack
-------------
---- Known loc
--------------
Low

Increased loc_stack () function is used for temporary stack management, call save_reg (), released by load ()
Like this
Before use
High
----- Known loc
----
---
----
---- Pop_stack
Low
loc_stack (size, 1)
After use
High
----- Known loc
---- Pop_stack
---
----
----
Low
2014-05-02 23:45:48 +08:00
jiang
6c8207633f Fixes include the double quotes bug
Added push_macro, pop_macro support
Fix pack bug, when output with-E will pack the bug
2014-05-02 11:23:54 +08:00
jiang
5b52a44b52 gen_putz () and struct_copy (), is to reduce the third-party call that
generates faster code tcc
Now only for x86-64
parse_number also to reduce the reliance on third-party libraries, allowing
faster analysis tcc
2014-05-02 09:42:33 +08:00
jiang
ee99fd45ab Add a comment.
ref: 2a8905c93b
Sorry, I used the wrong command, I did not mean it.
Thank grischka
2014-05-02 00:39:50 +08:00
grischka
504d40a328 Attention: never use hard tabs other than 8 (eight) wide
The attached fix (libcrt.c) is just one example.  There seem
many more such introduced from latest commits that look badly
formatted in anyone else's editors and should be fixed.

General recommended policy:
- if possible, do not add new hard tabs ('\t') at all.
  Use spaces (soft tabs) instead
- in any case, configure your editor to read/write hard tabs
  with width of 8 (eight)

Also:
- Avoid merge commits (unless for very good reason).  Instead
  use "git cherry-pick" or "git rebase" to put your commits on
  top of the public branch.  ref: 2a8905c93b

Also:
- jiang: please explain what you are doing, in the commit message
  and on the list. Subscribe to the mailing list to receive feedback
  from people for your work.

  For example, what was wrong with 'parse_number'? Show a test
  case and how your version fixes it (it is slower btw).
2014-05-01 15:33:29 +02:00
jiang
59a22d59a2 update for x86_64-gen.c 2014-05-01 20:58:43 +08:00
jiang
2742fbcf95 clean 2014-05-01 15:19:03 +08:00
jiang
87a850f553 fix its own making bug. Improved init_putz (). Modify the tests / Makefile to make the test more secure 2014-05-01 15:15:01 +08:00
jiang
9e3713facd Expansion code again for x86_64-gen 2014-05-01 01:48:50 +08:00
jiang
2b2e7f85d7 rename i386-tok.h i386-asm.c, add PRINTF_ASM_CODE 2014-04-30 19:30:30 +08:00
jiang
ba61fd9cd1 rename libtcc1.c 2014-04-30 17:35:44 +08:00
jiang
5af0ea7fb8 Fix va_arg bug, Fix type conversion bug, an increase of loc_stack () function is used to manage loc 2014-04-30 15:26:45 +08:00
jiang
9ff288648b Restore eda2c756ed 2014-04-30 14:24:44 +08:00
jiang
515169f21b Reduce the generation of machine code for x86_64, Less of size 2014-04-29 23:57:22 +08:00
jiang
2a8905c93b So that the generated code, and more short 2014-04-29 16:05:16 +08:00
Thomas Preud'homme
02e2fe3c26 Add support for load/store of _Bool value
Add support for loading _Bool value in i386, x86_64 and arm as well as
support for storing _Bool value on arm.
2014-04-29 16:01:57 +08:00
jiang
e20c1eb99e fix test3 for x86_64-gen.c 2014-04-28 19:43:02 +08:00
jiang
89f7aea980 fix abitest.c for x86_64 bug 2014-04-28 14:05:55 +08:00
jiang
deaee6c249 fix tccpp.c 2014-04-28 12:53:18 +08:00
jiang
857f7dbfa6 update static void parse_number(const char *p) for tccpp.c 2014-04-28 12:42:36 +08:00
jiang
4b50557553 add test for abitest.c 2014-04-28 12:28:56 +08:00
grischka
2ac238fc50 tccpe: adjust for new 'hidden' symbols feature
in order to avoid conflicts with windows specific (ab)usage
of the Elf32_Sym -> st_other field.
2014-04-17 17:01:28 +02:00
Thomas Preud'homme
6b7a6fcbc8 Improve efficiency of macro concatenation
As per grischka comment, always output a space after macro concatenation
instead of trying to detect if it's necessary as the current approach
has a huge cost.
2014-04-14 20:49:14 +08:00
Michael Matz
356c6f6293 Remove unused variable 2014-04-14 05:41:57 +02:00
Michael Matz
e69c506617 x86_64: Handle PLT relocs to hidden symbols
For calls to hidden symbols we don't need a PLT slot, rewrite
the reloc into PC32.
2014-04-14 04:58:05 +02:00
Michael Matz
a9fda392a0 Parse assembler .hidden directive
This makes TCCs assembler understand the '.hidden symbol' directive
(and emits a STV_HIDDEN ELF symbol then).
2014-04-14 03:33:50 +02:00
Michael Matz
fbda78aefe Parse and emit hidden visibility
This adds parsing of (GCC compatible) visibility attribute
in order to mark selected global symbols as hidden.  The generated
.o files contain hidden symbols already, the TCC linker doesn't
yet do the right thing.
2014-04-14 02:53:11 +02:00
grischka
112148172b tccpe: speed up .def file loading
The fgets replacement meant to work with "int fd"
was just too slow.
2014-04-13 20:30:46 +02:00
minux
aa255f37f2 tests2: fix and enable 46_grep test. 2014-04-12 14:04:10 -04:00
minux
0a51386960 tests2: fix 30_hanoi test and enable it. 2014-04-12 13:37:37 -04:00
Thomas Preud'homme
0e3d2e0bea Make build CPU detection a tad more flexible 2014-04-12 16:20:12 +08:00
Thomas Preud'homme
6e56bb387d Fix preprocessor concat with empty arg 2014-04-12 16:11:42 +08:00
minux
9714d2e75f build: add initial NetBSD support.
Not able to generate ELF files on NetBSD yet (lacks the note and crt1.o
is actually named crt0.o on NetBSD), but -run works with these extra
defines:
-D__lint__ -D"__symbolrename(x)=asm(#x)" -D__NetBSD__

The -D__lint__ is an ugly hack, TCC should be able to emulate GCC just
fine, but it seems TCC doesn't support __builtin_va_list yet?
	typedef __builtin_va_list __va_list;
/usr/include/sys/ansi.h:72: error: ';' expected (got "__va_list")
2014-04-12 01:42:46 -04:00
minux
469ae3a7e5 build: ignore and properly clean tests/vla_test 2014-04-12 01:10:58 -04:00
minux
b8eb7dd8e8 tcc.h: add ELF interpreter for DragonFly BSD. 2014-04-12 01:10:12 -04:00
minux
8d3e0b3080 tccrun: fix build on DragonFly BSD. 2014-04-12 00:52:20 -04:00
minux
5f7cdd29b6 win32/include/process.h: update prototypes to match mingw.
This eliminates an argument type mismatch warning during tcc
self-compilation on windows.
2014-04-12 00:09:57 -04:00
minux
df0267b287 tcc, libtcc: fix build on windows with latest mingw. 2014-04-11 23:49:53 -04:00
minux
bba1c381f4 tiny_impdef: remove artificial length restriction. 2014-04-11 23:23:05 -04:00
Urs Janssen
822f4630e3 add missing prototypes 2014-04-10 11:53:54 +02:00
Thomas Preud'homme
a715d7143d Prevent ## to appear at start or end of macro 2014-04-08 22:19:48 +08:00
Thomas Preud'homme
91d4db600b Add new tests for macro nesting 2014-04-07 23:30:57 +08:00
Thomas Preud'homme
c2422ba87f Fix test for macro nesting 2014-04-07 21:16:04 +08:00
Vincent Lefevre
3e9a7e9d69 Corrected spelling mistakes in comments and strings 2014-04-07 13:31:00 +02:00
Vincent Lefevre
d09a46d655 corrected a typo 2014-04-07 13:20:49 +02:00
grischka
f90bad0925 tests2: cleanup
- remove -norunsrc switch
  Meaning and usage (-run -norun...???) look sort of screwed.  Also
  general usefulness is unclear, so it was actually to support exactly
  one (not even very interesting) test

This partially reverts e31579b076
2014-04-07 11:20:45 +02:00
grischka
76accfb8d5 win32: libtcc1.a needs to be built with tcc
gcc/mingw produces msvc compatible pecoff objects, tcc only
knows ELF.
2014-04-07 11:16:06 +02:00
Michael Matz
f01373765b stdbool.h: Make conformant to ISOC99
For conformance to ISO C the stdbool.h header has to provide
the macro __bool_true_false_are_defined (defined to 1).  Yep,
that name is really in the standard.
2014-04-07 00:30:31 +02:00
Michael Matz
0961a38493 Declare wint_t in <stddef.h> when needed
Some old glibcs <wctype.h> require <stddef.h> to provide
wint_t, accomodate them.
2014-04-07 00:27:46 +02:00
grischka
0e43f3aef4 win32: warn people about using undeclared WINAPI functions
*** UNCONDITIONALLY ***

Esp. sihce tinycc winapi headers are not as complete as people might
expect this can otherwise lead to obscure problems that are difficult
to debug.

(Originally 'warn_implicit_function_declaration' was set to 1
always for windows but someone must have deleted that line)
2014-04-06 10:59:40 +02:00
Michael Matz
6a947d9d26 ELF: Remove traces of old RUNTIME_PLTGOT code
The last users of it went away, no use in keeping
this code.
2014-04-06 01:59:35 +02:00
Michael Matz
01c0419234 arm: Use proper PLT/GOT for -run.
Same as with x86_64, disable the runtime_plt_and_got hack
for -run on arm as well.  For that we need to handle several
relocations as (potentially) generating PLT slots as well.
Tested with mpfr-3.1.2 and gawk (both using --disable-shared),
there are two resp. five pre-existing problems, so no regressions.

This also works toward enabling real shared libs for arm,
but it's not there yet.
2014-04-06 01:50:35 +02:00
Michael Matz
9750d0b725 x86_64: Create proper PLT and GOT also for -run
This makes us use the normal PLT/GOT codepaths also for -run,
which formerly used an on-the-side blob for the jump tables.
For x86_64 only for now, arm coming up.
2014-04-06 00:30:22 +02:00
Michael Matz
c4427747e6 arm: Provide alloca()
This provides a simple implementation of alloca for ARM (and enables
the associated testcase).  As tcc for ARM doesn't contain an assembler,
we'll have to resort using gcc for compiling it.
2014-04-05 22:54:11 +02:00
Michael Matz
b0f8ca5e03 Git should ignore tests2 executables. 2014-04-05 22:52:17 +02:00
Michael Matz
3d18c9aa64 tests2: Build executables as well
The individual tests in tests2 are checked only with -run.  Build
(and check) executables as well, to test also building executables.
2014-04-05 17:35:00 +02:00
Michael Matz
0688afdd34 arm: Handle R_ARM_NONE relocs
These relocations are used to express a dependency on a certain
symbol (e.g. for EABIs exception handling to the
__aeabi_unwind_cpp_pr{0,1,2} routines).  Just ignore them in
reloc processing.
2014-04-04 23:33:04 +02:00
grischka
5879c854fb tccgen: x86_64: fix garbage in the SValue upper bits
This was going wrong (case TOK_LAND in unary: computed labels)
-        vset(&s->type, VT_CONST | VT_SYM, 0);
-        vtop->sym = s;

This does the right thing and is shorter:

+        vpushsym(&s->type, s);


Test case was:

    int main(int argc, char **argv)
    {
        int x;
        static void *label_return = &&lbl_return;
        printf("label_return = %p\n", label_return);
        goto *label_return; //<<<<< here segfault on linux X86_64 without the memset on vset
        printf("unreachable\n");
    lbl_return:
        return 0;
    }


Also::
- Rename "void* CValue.ptr" to more usable "addr_t ptr_offset"
  and start to use it in obvious cases.

- use __attribute__ ((noreturn)) only with gnu compiler

- Revert CValue memsets ("After several days searching ...")
  commit 4bc83ac393

Doesn't mean that the vsetX/vpush thingy isn't brittle and
there still might be bugs as to differences in how the CValue
union  was set and is then interpreted later on.

However the big memset hammer was just too slow (-3% overall).
2014-04-04 20:20:44 +02:00
Michael Matz
2024c44541 run: Always create .got relocs
When output is memory we applied the correct GOT offset for certain
relocations (e.g. _GOT32), but we forgot to actually fill the got
entries with the final symbol values, so unconditionally create relocs
against .got as well.
2014-04-04 17:54:52 +02:00
Michael Matz
f2c8491fc0 ELF: Make first PT_LOAD cover headers
This makes it so that the first PT_LOAD segment covers
ELF and program header and .interp (contained in the same page anyway,
right before the start of the first loaded section).  binutils
strip creates invalid output otherwise (which strictly is a binutils
bug, but let's be nice anyway).
2014-04-03 18:00:44 +02:00
Michael Matz
a913ee6082 x86-64: Use correct ELF values
The x86-64 uses different segment alignment (2MB) and a different
start address.
2014-04-03 17:59:41 +02:00
Michael Matz
ea2805f097 shared libs: Build libtcc1.a with -fPIC
TCCs runtime library must be compiled as position independend code,
so it can be linked into shared libraries.
2014-04-02 21:27:22 +02:00
Thomas Preud'homme
3e56584223 Allow local redefinition of enumerator 2014-03-31 22:59:10 +08:00
Vincent Lefevre
a620b12dc1 Fixed typo from commit 0ac8aaab1b 2014-03-31 15:24:32 +02:00
Thomas Preud'homme
01cf514e59 Update Changelog from git changelog entries 2014-03-31 19:42:42 +08:00
Michael Matz
0bd1282059 x86-64: shared libs improvement
This correctly resolves local references to global functions from
shared libs to their PLT slot (instead of directly to the target
symbol), so that interposition works.

This is still not 100% conforming (executables don't export symbols
that are also defined in linked shared libs, as they must), but
normal shared lib situations work.
2014-03-31 05:36:12 +02:00
Michael Matz
080ad7e62a x86-64: Add basic shared lib support
Initial support for shared libraries on x86-64.
2014-03-31 03:45:35 +02:00
mingodad
5a5fee867a Add __attribute__ ((noreturn)) to tcc_error and expect functions.
This make use of static analysis tools like scan-build report less false positives.
2014-03-30 10:18:18 +01:00
Thomas Preud'homme
80811671d4 Add tests for previous fixes
Add tests for the fixes made in commits
76cb1144ef,
a465b7f58f,
0f522fb32a,
82969f045c and
673befd2d7.
2014-03-30 12:56:55 +08:00
Thomas Preud'homme
fdc31e152b Update Changelog from git changelog entries 2014-03-30 12:35:22 +08:00
Daniel Glöckner
3900b235e0 x86_64: pass va_list as pointer
The ABI requires that va_list is passed as a pointer although its
contents is a kept in a structure. Therefore make it a single element
array.
2014-03-30 00:13:58 +01:00
grischka
0ac8aaab1b tccpp: reorder some tokens
... and make future reordering possibly easier

related to 9a6ee577f6
2014-03-29 19:37:26 +01:00
Daniel Glöckner
1075087241 ARM: Fix passing arrays to varadic functions
TinyCC miscompiled

void g(int,...);

void f(void)
{
        char b[4000];
        g(1, 2, 3, 4, b);
}

in two ways:
 1. It didn't align the stack to 8 bytes before the call
 2. It added sizeof(b) to the stack pointer after the call
2014-03-29 17:50:40 +01:00
Thomas Preud'homme
f272407353 Fix typo in code added by b018bac9c8 2014-03-29 14:57:59 +08:00
Thomas Preud'homme
b018bac9c8 Fix again GOT32 + PLT32 reloc commit
Fix commit aa561d7011 by setting
has_plt_entry once the plt has been created, not before.
2014-03-29 14:46:26 +08:00
Thomas Preud'homme
b125743323 Create bcheck region for argv and arge argument
For program manipulating argv or arge as pointer with construct such as:

(while *argv++) {
  do_something_with_argv;
}

it is necessary to have argv and arge inside a region. This patch create
regions argv and arge) if main is declared with those parameters.
2014-03-29 14:46:26 +08:00
Thomas Preud'homme
9a6ee577f6 Make get_tok_str support NULL as second param.
As was pointed out on tinycc-devel, many uses of get_tok_str gives as
second parameter the value NULL. However, that pointer was
unconditionally dereferenced in get_tok_ptr. This commit explicitely add
support for thas case.
2014-03-29 14:46:26 +08:00
mingodad
5c233f2cf3 The hack to allow valgrind works with tcc compiled programs
have the undesired side effect of programs compiled with
debug info segfaulting after debug info been striped
more tought must be done here
2014-03-28 21:07:06 +00:00
mingodad
c025478d7c New implementation of va_list/va_start/var_copy that do not use dynamic memory, with this when compiling fossil-scm with tcc on linux X86_64 it works fine. 2014-03-28 20:28:19 +00:00
mingodad
700c2f769b Remove the fix from my last commit, it was pointed by scan-build and is a false positive, thanks to grischka for pointing it. 2014-03-28 20:25:39 +00:00
mingodad
0ba7c8670c This allow valgrind to work on linux, some how the PHDR is missing and then valgrind complain with:
Inconsistency detected by ld.so: rtld.c: 1284: dl_main: Assertion `_rtld_local._dl_rtld_map.l_libname' failed!
2014-03-28 11:44:00 +00:00
mingodad
14bb8302c4 Fix a incorrect size for malloc. 2014-03-27 22:15:45 +00:00
mingodad
4bc83ac393 After several days searching why my code refactoring to remove globals was crashing,
I found the problem it was because CValue stack variables have rubish as it inital values
and assigning to a member that is smaller than the big union item and trying to
recover it later as a different member gives bak garbage.

ST_FUNC void vset(TCCState* tcc_state, CType *type, int r, int v)
{
    CValue cval;
    memset(&cval, 0, sizeof(CValue));

    cval.i = v; //,<<<<<<<<<<< here is the main bug that mix with garbage
    vsetc(tcc_state, type, r, &cval);
}

/* store a value or an expression directly in global data or in local array */
static void init_putv(TCCState* tcc_state, CType *type, Section *sec, unsigned long c,
                      int v, int expr_type)
{
...
        case VT_PTR:
            if (tcc_state->tccgen_vtop->r & VT_SYM) {
                greloc(tcc_state, sec, tcc_state->tccgen_vtop->sym, c, R_DATA_PTR);
            }

//<<< on the next line is where we try to get the assigned value to cvalue.i as cvalue.ull

            *(addr_t *)ptr |= (tcc_state->tccgen_vtop->c.ull & bit_mask) << bit_pos;
            break;

Also this patch makes vla tests pass on linux 32 bits
2014-03-26 20:18:48 +00:00
Thomas Preud'homme
aa561d7011 Simplify and fix GOT32 + PLT32 reloc commit
Introduce a new attribute to check the existence of a PLT entry for a
given symbol has the presence of an entry for that symbol in the dynsym
section is not proof that a PLT entry exists.

This fixes commit dc8ea93b13.
2014-03-26 23:13:28 +08:00
mingodad
bed865275d Add the generated executables ending with "-cc" and "-tcc" to the makefile "clean" 2014-03-26 14:32:03 +00:00
mingodad
ad9568060e A possible fix for the memory leak reported by valgrind when running tcctest.c with tcc. 2014-03-25 18:06:14 +00:00
Thomas Preud'homme
dc8ea93b13 Support GOT32 and PLT32 reloc for same symbol
Some symbol (such as __gmon_start__ but this one does not matter to tcc)
can have both a R_386_GOT32 and R_386_PLT32 relocation. It is thus not
enough to test if a GOT reloc was already done when deciding whether to
return early from put_got_entry.
2014-03-25 22:35:11 +08:00
Thomas Preud'homme
078ba241d9 Always link libtcc1.a in (useful for va_* on x86)
On x86 tcc call to function in libtcc1.a to implement va_* functions.
2014-03-25 21:18:57 +08:00
Thomas Preud'homme
f1f45a47ef Add test for previous commit
* Adapt tests2 Makefile to support testing tcc error reporting
* Add test for previous commit
2014-03-25 20:54:19 +08:00
Thomas Preud'homme
6f6ed8acc7 Warn about soft float ABI not being supported
For ARM target, tcc uses the soft float ABI when not asked to use hard
float ABI. This means machine without a VFP co-processor generate code
that they cannot run. This commit add a warning for such cases.
2014-03-25 19:58:12 +08:00
Thomas Preud'homme
b8610f14b0 Deprecate FPA and OABI support for ARM 2014-03-25 19:58:03 +08:00
Thomas Preud'homme
b68499e971 Make parse_btype only accept one basic type
This makes int char c; and struct {} int c; generate an error. Thanks
Mobi Phil for reporting.
2014-03-24 23:40:39 +08:00
Thomas Preud'homme
ec1c83081d Fix relocation of __bound_init
When bound check is enabled, tcc tries to relocate a call to
__bound_init in _init. This means that relocation (in tcc_add_bcheck)
must be done after libtcc1.a (which countains __bound_init) is loaded
but before crtn.o is loaded as this finalize _init.
2014-03-17 23:14:38 +08:00
Thomas Preud'homme
40e3859739 Fix __clear_cache implementation
Forgot to give the parameters to syscall function, doh!
2014-03-11 22:57:22 +08:00
Thomas Preud'homme
b2192fc50b Adjust relocation offset for thumb to ARM veneer 2014-03-11 21:45:52 +08:00
Thomas Preud'homme
d3d89900f6 Don't hardcode gcc in tests Makefile 2014-03-09 22:54:48 +08:00
Thomas Preud'homme
62d1da1b3e Fix warning of clang 2014-03-09 22:54:30 +08:00
Thomas Preud'homme
98afe11c85 Use intptr_t to cast pointer 2014-03-09 22:22:43 +08:00
Thomas Preud'homme
73ac39c317 Undefine __va* in libtcc1 to avoid errors w/ clang 2014-03-09 22:22:21 +08:00
Thomas Preud'homme
e50f08faa1 Make condition in libtcc1 based on target
Prior to this commit runtime library was compiled according to the host
because of the macro used to detec what architecture to choose. This
commit fixes this by using the TARGET_* macro instead.
2014-03-09 22:15:01 +08:00
Thomas Preud'homme
33cea54dc7 Fix type_to_str test for unsigned int 2014-03-09 13:32:40 +08:00
Thomas Preud'homme
fdb3b10d06 Fix various errors uncovered by static analysis
Reported-by: Carlos Montiers <cmontiers@gmail.com>
2014-03-08 18:38:49 +08:00
Austin English
ba286136bf libtcc: ignore linker optizimization and as-needed options. This allows compiling some packages from Gentoo's portage 2014-03-06 12:29:19 -08:00
Thomas Preud'homme
361ec4f98e Call fill_got_entry unconditionally
Call fill_got_entry unconditionally from fill_got so as to avoid
warnings on !x86-64 architectures. This can be done since this code path
is only followed by x86-64 architecture anyway.
2014-02-10 21:35:00 +08:00
Thomas Preud'homme
c6017182f6 Define float_eabi only in arm-gen.o 2014-02-09 23:31:58 +08:00
Austin English
497f9393e0 conftest: fix globbing to match MSVC 2014-02-08 14:38:41 -08:00
Christian Jullien
b46f7461a3 Fix warning about undeclared __clear_cache function call. 2014-02-08 08:31:32 +01:00
Thomas Preud'homme
d0dae7f241 Ignore VT_DEFSIGN in load on x86-64 arch
This fixes commit b0b5165d16 for x86-64
targets.
2014-02-07 22:31:44 +08:00
Thomas Preud'homme
b0b5165d16 Def signedness != signed != unsigned for char
When checking for exact compatibility between types (such as in
__builtin_types_compatible_p) consider the case of default signedness to
be incompatible with both of the explicit signedness for char. That is,
char is incompatible with signed char *and* unsigned char, no matter
what the default signedness for char is.
2014-02-06 21:40:22 +08:00
Thomas Preud'homme
e571850d79 Add support of Thumb to ARM branch relocation 2014-02-06 21:38:24 +08:00
Thomas Preud'homme
4aec2902ca Split elf_output_file in smaller functions 2014-02-06 19:38:28 +08:00
Thomas Preud'homme
55f751ac6d Add macro to browse reloc and sym entries
Introduce for_each_elem to browse relocation entries and symbols of a
section.
2014-02-06 19:38:24 +08:00
Thomas Preud'homme
88c9f1bb4e Round mode of ll -> float conversion to nearest
Change rounding mode of long long to float conversion to nearest in
libtcc1.
2014-02-05 20:56:36 +08:00
Thomas Preud'homme
d029507494 Fix negative long long to float conversion on ARM 2014-02-05 16:56:27 +08:00
Thomas Preud'homme
0ab07f39a6 Fix float to long long conversion on ARM
Fix float to long long conversion on ARM when the result would fit in an
int.
2014-02-05 16:09:54 +08:00
Thomas Preud'homme
02d2ca8ac7 Fix and extend *FCAST test in tcctest.c
Result of float to unsigned integer conversion is undefined if float is
negative. This commit take the absolute value of the float before doing
the conversion to unsigned integer and add more float to integer
conversion test.
2014-02-05 15:26:46 +08:00
Thomas Preud'homme
17314a1fb3 Fix parameter passing of long long bitfield 2014-02-04 20:55:24 +08:00
Thomas Preud'homme
4e5f15c685 switch last 2 params of TOK_memset on ARM
On ARM, TOK_memset is executed via __aeabi_memset which reverse the
order of the last two parameters.
2014-02-03 22:28:08 +08:00
Thomas Preud'homme
1415d7e6b6 Don't perform builtin_frame_address on ARM 2014-02-03 12:28:25 +08:00
Thomas Preud'homme
4760804dba Fix fct param passing of struct with size < 4 2014-02-03 11:13:42 +08:00
Thomas Preud'homme
9fc57302f8 Switch float abi to softfp for int <--> float conv
This improves commit 5cbe03b9c4 by
avoiding a double transfer when the default float ABI is already softfp.
It's also more clean by expliciting that the ABI is simply changed for
runtime ABI functions.
2014-02-02 20:29:24 +08:00
Thomas Preud'homme
2eb844f8b5 Revert "Add macro to browse reloc and sym entries"
This reverts commit 3cbc7a2dcc.
2014-02-02 20:02:12 +08:00
Thomas Preud'homme
e5a706a091 Revert "Split elf_output_file in smaller functions"
This reverts commit b5b82df3e3.
2014-02-02 20:02:11 +08:00
Thomas Preud'homme
f62e97e0ed Revert "Add support of Thumb to ARM branch relocation"
This reverts commit 8635939b8d.
2014-02-02 20:02:08 +08:00
Thomas Preud'homme
8635939b8d Add support of Thumb to ARM branch relocation 2014-02-02 17:23:15 +08:00
Thomas Preud'homme
b5b82df3e3 Split elf_output_file in smaller functions 2014-02-02 17:23:15 +08:00
Thomas Preud'homme
3cbc7a2dcc Add macro to browse reloc and sym entries
Introduce for_each_elem to browse relocation entries and symbols of a
section.
2014-02-02 17:23:15 +08:00
Thomas Preud'homme
599677a5e2 Give ARM asm mnemonic of PLT entries
Give ARM assembly mnemonic of PLT entries in put_got_entry
2014-02-02 17:23:15 +08:00
Thomas Preud'homme
3d4b57ffe3 Clean tccelf.c
- remove debug printf and commented out code
- remove C++-like comments
- remove whitespace at end of lines
- replace tabs by spaces
2014-02-02 17:23:14 +08:00
Thomas Preud'homme
6f3569e4e2 Ignore abitest-cc and abitest-tcc test programs 2014-02-02 17:23:14 +08:00
Thomas Preud'homme
c88c2706a2 Test long long to float conversions 2014-02-01 15:31:28 +08:00
Thomas Preud'homme
5cbe03b9c4 Move result of itof double conv back to VFP reg
EABI functions to convert an int to a double register take the integer
value in core registers and also give the result in core registers.
It is thus necessary to move the result back to VFP register after the
function call. This only affected integer to double conversion because
integer to float conversion used a VFP instruction to do the conversion
and this obviously left the result in VFP register. Note that the
behavior is left untouched for !EABI as the correct behavior in this
case is unknown to the author of this patch.
2014-02-01 14:25:13 +08:00
Iavael
fad8e13ccd Ordinary and implicit rules cannot be mixed in the same string in Makefile 2014-01-23 21:40:08 +04:00
grischka
32a4962593 tcctest: add back testXb (self compile with -b)
- Thanks to Kirill "tcc -b itself" should work now
  (was removed in d5f4df09ff)

Also:

- tests/Makefile:
  - fix spurious --I from 767410b875
  - lookup boundtest.c via VPATH (for out-of-tree build)
  - test[123]b?: fail on diff error
  - Windows: test3 now works (from e31579b076)
  - abitest: a libtcc.a made by gcc is not usable for tcc
    on WIndows - using source instead (libtcc.c)

- tccpe:
  - avoid gcc warning (x86_64)
2014-01-21 13:25:14 +01:00
Austin English
48ad93983f workaround a wine cmd bug in build-tcc.bat 2014-01-20 02:23:34 -08:00
Kirill Smelkov
75118780da tccrun: Mark argv area as valid for bcheck
On my x86_64 box in i386 mode with address space randomization turned off,
I've observed the following:

    tests$ ../tcc -B.. -b -run boundtest.c 1
    Runtime error: dereferencing invalid pointer
    boundtest.c:222: at 0x808da73 main()

With diagnostic patch (like in efd9d92b "lib/bcheck: Don't assume heap
goes right after bss") and bcheck traces for __bound_new_region,
__bound_ptr_indir, etc... here is how the program run looks like:

    >>> TCC

    etext:   0x8067ed8
    edata:   0x807321d
    end:     0x807d95c
    brk:     0x807e000
    stack:  0xffffd0b4
    &errno: 0xf7dbd688
    mark_invalid  0xfff80000 -      (nil)
    mark_invalid   0x80fa000 - 0x100fa000
    new  808fdb0  808ff40  101  101  fd0  ff0
    new  808ff44  808ff48  101  101  ff0  ff0
    new  808ff49  8090049  101  101  ff0 1000
    new  808fd20  808fd29  101  101  fd0  fd0
    new  808fd2c  808fd6c  101  101  fd0  fd0
    new  808fd6d  808fda0  101  101  fd0  fd0
    E: __bound_ptr_indir4(0xffffd184, 0x4)
    Runtime error: dereferencing invalid pointer
    boundtest.c:222: at 0x808ea83 main()

So we are accessing something on stack, above stack entry for compiled
main. Investigating with gdb shows that this is argv:

    tests$ gdb ../tcc
    Reading symbols from /home/kirr/src/tools/tinycc/tcc...done.
    (gdb) set args -B.. -b -run boundtest.c 1
    (gdb) r
    Starting program: /home/kirr/src/tools/tinycc/tests/../tcc -B.. -b -run boundtest.c 1
    warning: Could not load shared library symbols for linux-gate.so.1.
    Do you need "set solib-search-path" or "set sysroot"?

    >>> TCC

    etext:   0x8067ed8
    edata:   0x807321d
    end:     0x807d95c
    brk:     0x807e000
    stack:  0xffffd074
    &errno: 0xf7dbd688
    mark_invalid  0xfff80000 -      (nil)
    mark_invalid   0x80fa000 - 0x100fa000
    new  808fdb0  808ff40  101  101  fd0  ff0
    new  808ff44  808ff48  101  101  ff0  ff0
    new  808ff49  8090049  101  101  ff0 1000
    new  808fd20  808fd29  101  101  fd0  fd0
    new  808fd2c  808fd6c  101  101  fd0  fd0
    new  808fd6d  808fda0  101  101  fd0  fd0
    E: __bound_ptr_indir4(0xffffd144, 0x4)

    Program received signal SIGSEGV, Segmentation fault.
    0x0808ea83 in ?? ()
    (gdb) bt
    #0  0x0808ea83 in ?? ()
    #1  0x080639b3 in tcc_run (s1=s1@entry=0x807e008, argc=argc@entry=2, argv=argv@entry=0xffffd144) at tccrun.c:132
    #2  0x080492b0 in main (argc=6, argv=0xffffd134) at tcc.c:346
    (gdb) f 1
    #1  0x080639b3 in tcc_run (s1=s1@entry=0x807e008, argc=argc@entry=2, argv=argv@entry=0xffffd144) at tccrun.c:132
    132             ret = (*prog_main)(argc, argv);
    132             ret = (*prog_main)(argc, argv);
    (gdb) p argv
    $1 = (char **) 0xffffd144

So before running compiled program, mark argv as valid region and we are
done - now the test passes.

P.S. maybe it would be better to just mark the whole vector kernel passes to
program (argv, env, auxv, etc...) as valid all at once...
2014-01-19 16:47:51 +04:00
Vincent Lefevre
262eec3e83 Fixed the LDBL_* macros in include/float.h for x86-64: as said
when x86-64 support was added, "for long double, we use x87 FPU".
And indeed, tests show that Intel's extended precision is used,
not double precision.
2014-01-12 22:26:09 +01:00
Iavael
8e724128e8 Revert "Use anonymous file instead of regular file to back mmap"
This reverts commit 935d8169b8,
because two anonymous mappings would have different content,
while they must have the same one.
2014-01-12 09:29:30 +04:00
Michael Matz
f42a02efda tcctest: One more signed zero test
This also checks that -(-0.0) is +0.0.
2014-01-12 04:53:29 +01:00
Michael Matz
05c9b76131 Fix floating point unary minus and plus
negate(x) is subtract(-0,x), not subtract(+0,x), which makes
a difference with signed zeros.  Also +x was expressed as x+0,
in order for the integer promotions to happen, but also mangles signed
zeros, so just don't do that with floating types.
2014-01-12 04:44:27 +01:00
Michael Matz
9c6ddbfe90 Fix compile on ARM non-eabi and non-vfp
Adjust arm_init prototype to match declaration.
2014-01-11 23:44:41 +01:00
Michael Matz
9e11476e15 Fix Fixes for PE x86_64 for fail in code
Applying 64bit relocs assumes that the CVal is initialized to zero
for the whole 64bit.  Consolidate this a bit, at the same time
zeroing the .ull member more consistently when needed.  Fixes segfault
on x86_64-linux using global vars in tcctest.c.
2014-01-11 23:42:58 +01:00
keren
80b36ab628 Fix missing mem_size assignment when using mmap() 2014-01-10 10:23:11 -08:00
Archidemon
fdf9fba578 Fixes previous fixes 2014-01-10 11:58:16 +06:00
Archidemon
ea7b17f641 Fixes for PE x86_64 for fail in code
int (*fn1)=0x13fde16b5;

and

int fn1(int a) {...}

struct {
  int (*fn2)(int a);
} b = { fn1 };
2014-01-10 09:45:18 +06:00
keren
935d8169b8 Use anonymous file instead of regular file to back mmap
Signed-off-by: Keren Tan <tankeren@gmail.com>
2014-01-09 14:00:19 -08:00
Thomas Preud'homme
767410b875 Various Makefile fixes for cross-compilation
- Build libtcc1 for cross-compiler on arm (arm to X cross compilers)
- Install libtcc1 and includes for arm to i386 cross compiler
- Add basic check of cross-compilers (compile ex1.c)
2014-01-09 17:15:08 +08:00
Thomas Preud'homme
da0601e490 Remove WITHOUT_LIBTCC macro: no more user 2014-01-08 21:32:53 +08:00
Thomas Preud'homme
bf2854d2a2 Use GNU triplet prefix for cross tcc compilers
Compatibility symlinks are put in place in case some script were relying
on former names except for CMake since it was added after last release.
2014-01-08 21:07:59 +08:00
Thomas Preud'homme
3352cb8aef Shared libraries also have entry points
This fix commit 32734680cb
2014-01-08 18:10:02 +08:00
Thomas Preud'homme
32734680cb Improve ELF on ARM
* set whether soft or hardfloat calling convention is used
* mark ELF file has having an entry point when there is
2014-01-08 17:59:16 +08:00
Thomas Preud'homme
28f0286479 Update elf.h 2014-01-08 17:38:31 +08:00
Thomas Preud'homme
b6247d1f3c Add support for runtime selection of float ABI 2014-01-08 15:00:52 +08:00
Thomas Preud'homme
70a088af87 Explicit that EABI only supports VFP for now 2014-01-07 23:20:31 +08:00
Thomas Preud'homme
58f3b7781b Don't say compiler flags are warning options 2014-01-07 23:20:31 +08:00
Vincent Lefevre
99851b0d9e fixed permissions for install on Unix
Signed-off-by: Vincent Lefevre <vincent@vinc17.net>
2014-01-07 16:05:31 +01:00
grischka
3fe2a95d7f be stricter with aliasing
Refactoring (no logical changes):
- use memcpy in tccgen.c:ieee_finite(double d)
- use union to store attribute flags in Sym
Makefile: "CFLAGS+=-fno-strict-aliasing" basically not necessary
anymore but I left it for now because gcc sometimes behaves
unexpectedly without.

Also:
- configure: back to mode 100755
- tcc.h: remove unused variables tdata/tbss_section
- x86_64-gen.c: adjust gfunc_sret for prototype
2014-01-07 14:57:07 +01:00
grischka
2bd0daabbe misc. fixes
- tccgen: error out for cast to void, as in
      void foo(void) { return 1; }
  This avoids an assertion failure in x86_64-gen.c, also.
  also fix tests2/03_struct.c accordingly

- Error: "memory full" - be more specific

- Makefiles: remove circular dependencies, lookup tcctest.c from VPATH

- tcc.h: cleanup lib, include, crt and libgcc search paths"
  avoid duplication or trailing slashes with no CONFIG_MULTIARCHDIR
  (as from 9382d6f1a0)

- tcc.h: remove ";{B}" from PE search path
  in ce5e12c2f9 James Lyon wrote:
  "... I'm not sure this is the right way to fix this problem."
  And the answer is: No, please. (copying libtcc1.a for tests instead)

- win32/build_tcc.bat: do not move away a versioned file
2014-01-06 19:56:26 +01:00
grischka
d443644de3 tccpe: cleanup "imports per ordinal"
- tccpe.c: avoid conflict with imp_sym->st_value, cleanup
- _parseLibs.bat, _tcc.bat: no instructions for usage, removed.

from commit 642b6d0f50
2014-01-06 19:32:50 +01:00
grischka
4ad186c5ef i386: use __fixdfdi instead of __tcc_cvt_ftol
Variants __fixsfdi/__fixxfdi are not needed for now because
the value is converted to double always.

Also:
- remove __tcc_fpinit for unix as it seems redundant by the
  __setfpucw call in the startup code
- avoid reference to s->runtime_main in cross compilers
- configure: fix --with-libgcc help
- tcctok.h: cleanup
2014-01-06 19:07:08 +01:00
Thomas Preud'homme
8efaa71190 Fix struct ret in variadic fct with ARM hardfloat
The procedure calling standard for ARM architecture mandate the use of
the base standard for variadic function. Therefore, hgen float aggregate
must be returned via stack when greater than 4 bytes and via core
registers else in case of variadic function.

This patch improve gfunc_sret() to take into account whether the
function is variadic or not and make use of gfunc_sret() return value to
determine whether to pass a structure via stack in gfunc_prolog(). It
also take advantage of knowing if a function is variadic or not move
float result value from VFP register to core register in gfunc_epilog().
2014-01-06 22:57:05 +08:00
Thomas Preud'homme
bcc1904f9c Don't call __tcc_fpinit if using libgcc 2014-01-06 11:26:09 +08:00
Thomas Preud'homme
a01d83d783 Don't enable bound check if libgcc is used
Bound check rely on some functions provided by libtcc. It should
therefore not be enabled when libgcc is used.
2014-01-06 11:26:09 +08:00
Daniel Glöckner
5078a06e91 Relicensing TinyCC
I'm fine with relicensing all my contributions to files other than
arm-gen.c.
2014-01-04 15:35:26 +01:00
Thomas Preud'homme
eda2c756ed Move logic for if (int value) to tccgen.c
Move the logic to do a test of an integer value (ex if (0)) out of
arch-specific code to tccgen.c to avoid code duplication. This also
fixes test of long long value which was only testing the bottom half of
such values on 32 bits architectures.
2014-01-04 21:10:05 +08:00
Thomas Preud'homme
c634c797c5 Update Changelog from git changelog entries 2014-01-04 21:10:05 +08:00
Daniel Glöckner
9e9e5c2929 Relicensing TinyCC 2014-01-04 10:59:04 +01:00
Thomas Preud'homme
3eed3506b4 Fix negation of 0.0 and -0.0 2014-01-04 17:07:58 +08:00
Thomas Preud'homme
0382131c6f Provide install-strip target in Makefile 2014-01-04 09:48:45 +08:00
Thomas Preud'homme
9e79b18bca Use libtcc.a for static link even with USE_LIBGCC
When statically linking, runtime library should be static as well. tcc
could link with libgcc.a but it's in a gcc version specific directory.
Another solution, followed by this patch, is to use libtcc.a when
statically linking, even if USE_LIBGCC was configured.
2014-01-03 18:20:51 +08:00
Thomas Preud'homme
e0e9a2a295 Report error on NaN comparison
Use comisd / fcompp for float comparison (except TOK_EQ and TOK_NE)
instead of ucomisd / fucompp to detect NaN comparison.

Thanks Vincent Lefèvre for the bug report and for also giving the
solution.
2014-01-03 10:19:38 +08:00
Thomas Preud'homme
59b8007f98 Always set *palign in classify_x86_64_arg
Set *palign for VT_BITFIELD and VT_ARRAY types in classify_x86_64_arg as
else you happen to have in *palign what was already there. This can
cause gfunc_call on !PE systems to consider an array as 16 bytes align
and trigger the assert if the previous argument was 16 bytes aligned.
2014-01-03 10:19:38 +08:00
grischka
fbc8810334 Fix "Add support for struct > 4B returned via registers"
- avoid assumption "ret_align == register_size" which is
  false for non-arm targets
- rename symbol "sret" to more descriptive "ret_nregs"

This fixes commit dcec8673f2

Also:
- remove multiple definitions in win32/include/math.h
2013-12-16 15:38:10 +01:00
Thomas Preud'homme
46dd2971ab make git ignore lib/arm directory 2013-12-15 09:49:20 +08:00
Thomas Preud'homme
a24e31e85d Fix signed integer division in ARM runtime ABI
- fix computation of absolute value (clearing the sign bit does not
  since integers are encoded in 2's complement)
- test sign of integer in a more conventional way (binary and with the
  high bit does not work for long long due to a bug in gtst)
- spacing in include
2013-12-15 09:44:20 +08:00
Thomas Preud'homme
f2dbcf7594 Add ARM aeabi functions needed to run tcctest
Add implementation for float / integer conversion functions:
  __aeabi_d2lz, __aeabi_d2ulz, __aeabi_f2lz, __aeabi_f2ulz, __aeabi_l2d,
  __aeabi_l2f, __aeabi_ul2d, __aeabi_ul2f

Add implementation for long long helper functions:
  __aeabi_ldivmod, __aeabi_uldivmod, __aeabi_llsl, __aeabi_llsr, __aeabi_lasr

Add implementation for integer division functions:
  __aeabi_uidiv, __aeabi_uidivmod, __aeabi_idiv, __aeabi_idivmod,
2013-12-11 10:15:30 +08:00
Thomas Preud'homme
389c25c4b9 Support special calling convention for runtime ABI
Add infrastructure to support special calling convention for runtime ABI
function no matter what is the current calling convention. This involve
2 changes:
- behave as per base standard in gfunc_call
- move result back in VFP register in gen_cvt_itof1
2013-12-11 10:15:29 +08:00
Thomas Preud'homme
3676f61983 Define __ARM_EABI__ and __ARMEL__ when applicable 2013-11-26 12:06:21 +08:00
Thomas Preud'homme
5919da6f05 Make abitest.c have predictable result
stdarg_test in abitest.c relies on a sum of some parameters made by both
the caller and the callee to reach the same result. However, the
variables used to store the temporary result of the additions are not
initialized to 0, leading to uncertainty as to the results. This commit
add this needed initialization.
2013-11-25 11:25:04 +08:00
Thomas Preud'homme
4260ce1889 Add va_* macro implementation for ARM 2013-11-25 11:24:02 +08:00
Thomas Preud'homme
82b257c29c Add comment to explain the code added by 41ce391c
Add a comment in arm-gen.c to explain how commit
41ce391c86 solves the register corruption
when passing a structure in a function call.
2013-11-25 11:00:51 +08:00
Thomas Preud'homme
48fc746652 Fix structure passing in ARM calling convention
Fix the address on stack where a structure is copied when it is a
parameter of a function call. This address must be computed from the
stack pointer and a possible padding offset.
2013-11-25 10:58:00 +08:00
Thomas Preud'homme
dcec8673f2 Add support for struct > 4B returned via registers
On ARM with hardfloat calling convention, structure containing 4 fields
or less of the same float type are returned via float registers. This
means that a structure can be returned in up to 4 double registers in a
structure is composed of 4 doubles. This commit adds support for return
of structures in several registers.
2013-11-22 09:27:15 +08:00
Thomas Preud'homme
d9d60a1ebd Remove code in arm-gen.c for struct packing in reg
Struct packing in register is now handled since commit 2bbfaf43 by
tccgen.c proper.
2013-11-22 00:15:34 +08:00
Thomas Preud'homme
63a84713ee Correctly identify homogeneous float aggregate
First related symbol of a structure justs indicate its size. This first
member is the second related symbol.
2013-11-22 00:13:05 +08:00
Thomas Preud'homme
c3e7c725b5 Fix counting of VFP regs in ARM's gfunc_prolog
Fix in gfunc_prolog for ARM the counting of the highest numbered VFP
float register used for parameter passing, rounded to 2. It can be
computed from the range of VFP float register with the highest range
start and adding the number of VFP float register occupied. This ensure
that parameter of type struct that spans over more than 2 float
registers are correctly taken into account.
2013-11-21 22:27:15 +08:00
Thomas Preud'homme
41ce391c86 Fix register corruption at function call on ARM
Prior to this commit, params could use some registers that do not appear
in the value stack. Therefore when generating function call, one of such
register could be reused, leading to wrong parameter content. This
happens when a structure is passed via core register, as only the first
register would appear in the value stack.
2013-11-21 21:09:44 +08:00
Thomas Preud'homme
1b606d1884 Allow thumb transition for R_ARM_PC24
Allow bl -> blx conversion in the case of R_ARM_PC24 relocation with
instruction being an unconditional bl. Also make spacing more uniform.
2013-11-18 00:03:38 +08:00
Thomas Preud'homme
0c40bc8982 Correctly align and reclaim stack at function call
* Correctly align stack in case of structure split between core
  registers and stack
* Correctly reclaim stack space after function call in the case where
  the stack needed padding to be aligned at function call.
2013-11-17 18:26:56 +08:00
Thomas Preud'homme
1528a08540 Refactor and simplify gfunc_call() on arm 2013-11-15 17:57:31 +08:00
Joseph Poirier
0650ab01c8 struct variable behind guard, proper macro check, and remove some whitespace.
Wrap runtime_main as per its declaration in tcc.h.
Fix preprocessor check for TCC_ARM_EABI macro definition.

Signed-off-by: Joseph Poirier <jdpoirier@gmail.com>
2013-11-08 13:24:15 -06:00
Thomas Preud'homme
fbb4841606 Add __clear_cache implementation in libtcc1
Add __clear_cache function for flushing caches to libtcc1.
2013-11-05 19:29:43 +08:00
Thomas Preud'homme
b7d017dec8 Fix allocation of struct in registers on ARM
Allocation of struct in core and/or VFP registers on ARM is made by
manipulating the value stack to create 3 distinct zones: parameters
allocated on stack, parameters of type struct allocated in core
registers and parameters of type struct allocated in VFP registers.
Parameters of primitive type can be in any zone. This commit change the
order of the zones from stack, VFP, core to stack, core, VFP (from
highest addresses to lowest ones) in order to correctly deal the
situation when structures are allocated both in core and VFP registers.
2013-11-05 17:50:30 +08:00
Thomas Preud'homme
cf02f920c1 Revert "Add support for thread-local storage variables"
TLS support in tinyCC is absolutely not ready:
- segment register not select in load and store
- no relocation added for computing offset of per-thread symbol
- no support for TLS-specific relocations
- no program header added as per Drepper document about TLS

This reverts commit 1c4afd1350.
2013-11-03 18:55:54 +08:00
Thomas Preud'homme
1c4afd1350 Add support for thread-local storage variables 2013-10-29 22:10:02 +08:00
Amine Najahi
3b07a15fd1 Detect usage of incomplete types inside struct/union
Make sure the only exception is for a flexible array member
as the last element of a structure
2013-10-06 14:51:29 +02:00
Ramsay Jones
d0c2f00df2 Fix CONFIG_TCC_SYSINCLUDEPATHS on !win32 systems
Commit 9382d6f1 ("Fix lib, include, crt and libgcc search paths",
07-09-2013) inadvertently included an initial empty entry to the
CONFIG_TCC_SYSINCLUDEPATHS variable (for non win32 targets). In
addition to an empty line in the 'tcc -vv' display, this leads
to the preprocessor attempting to read an include file from the
root of the filesystem (i.e. '/header.h').

Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
2013-10-02 21:49:55 +02:00
Thomas Preud'homme
385a86b000 Fix commit 0f5942c6b3 2013-10-01 17:11:44 +02:00
Thomas Preud'homme
0f5942c6b3 Avoid warnings with gcc 4.8 + default CFLAGS 2013-09-24 15:37:12 +02:00
Thomas Preud'homme
a1a691a030 Detect correct instruction with incorrect operands
Display a different warning when an instruction is recognized by tcc but
the operands found do not correspond to the constraints of the
instruction.
2013-09-24 15:37:11 +02:00
Vittorio Giovara
45b35a3d66 set the user-defined library search paths first 2013-09-23 09:40:06 +02:00
Thomas Preud'homme
673befd2d7 Report error when redefining enumerator
Prevent the following code from compiling:

enum color {RED, GREEN, BLUE};
enum rgb {RED, G, B};
2013-09-20 22:49:49 +02:00
Thomas Preud'homme
82969f045c Report error when using undefined enum
Prevent the following code from compiling:

int main(void)
{
	enum rgb c = 42;
	return c;
}

Reported-by: John Haque <j.eh@mchsi.com>
2013-09-20 21:22:11 +02:00
Thomas Preud'homme
0f522fb32a Forbid enum redefinition.
Prevent the following code from compiling:

enum color {RED, GREEN, BLUE};
enum color {R, G, B};

int main()
{
        return R;
}

Reported-by: John Haque <j.eh@mchsi.com>
2013-09-20 01:06:43 +02:00
Thomas Preud'homme
a465b7f58f Forbid the use of array of functions
Prevent the following code from compiling:

int (*fct)[42](int x);

Reported-by: Abdul Wadud Mohammad Mohibur Rashid <mohibur_rashid@yahoo.com>
2013-09-19 18:58:46 +02:00
YX Hao
642b6d0f50 Add the possibility to use noname functions by ordinal
tcc.c:
process.h:177:20: note: expected 'char * const*' but argument is of type 'char const*const*'

tccpe.c:
Add the possibility to use noname functions by ordinal.
use def file: "AliasName @n"

build-tcc.bat:
1. Enable 32 bits mode on 64 bits OS.
2. build doc.

_parseLibs.bat:
Convenient to use "*.def + *.c" instead of *.a, just use -l*

_tcc.bat:
a practice of _parseLibs.bat

Signed-off-by: YX Hao <lifenjoiner@163.com>
2013-09-19 21:50:38 +08:00
Thomas Preud'homme
76cb1144ef Generate an error when a function is redefined
Use one more bit in AttributeDef to differenciate between declared
function (only its prototype is known) and defined function (its body is
also known). This allows to generate an error in cases like:

int f(){return 0;}
int f(){return 1;}
2013-09-16 14:48:33 +02:00
grischka
13b997668e win32: fix libtcc support
For "tcc -run file.c", I was trying to initialize the FP control
in a function in libtcc1.a (_runmain) before calling main.

Unfortunately that turned out to cause problems with for example
libtcc_test since such usage doesn't necessarily define a 'main'
function.

So for tcc -run we're back to relying on the FP control word
that is set in the startup code of tcc.exe rsp. libtcc.dll.

This fixes part of commit 73faaea227
2013-09-10 15:36:56 +02:00
Ramsay Jones
235a65033f libtcc1.c: Fix __asm__() in __tcc_fpinit and __tcc_cvt_ftol
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
2013-09-09 23:59:09 +02:00
Thomas Preud'homme
9382d6f1a0 Fix lib, include, crt and libgcc search paths 2013-09-07 19:28:06 +02:00
grischka
73faaea227 i386-gen: preserve fp control word in gen_cvt_ftoi
- Use runtime function for conversion
- Also initialize fp with tcc -run on windows

This fixes a bug where
  double x = 1.0;
  double y = 1.0000000000000001;
  double z = x < y ? 0 : sqrt (x*x - y*y);
caused a bad sqrt because rounding precision for the x < y comparison
was different to the one used within the sqrt function.

This also fixes a bug where
  printf("%d, %d", (int)pow(10, 2), (int)pow(10, 2));
would print
  100, 99

Unrelated:
  win32: document relative include & lib lookup
  win32: normalize_slashes: do not mirror silly gcc behavior
  This reverts part of commit 8a81f9e103
  winapi: add missing WINAPI decl. for some functions
2013-08-28 22:55:05 +02:00
grischka
69c2e7f96c tccgen: fix crash with undeclared struct
... as in:
    #include<stdio.h>
    int main()
    {
        struct asdasd x;
        printf("%d\n", sizeof(x));
    }
This fixes commit 17571298f3
2013-07-24 17:06:13 +02:00
Frédéric Féret
8c033a1461 Relicensing TinyCC 2013-06-22 16:18:49 +02:00
Thomas Preud'homme
37b0348993 Define __ARM_PCS_VFP in hardfloat compilation mode 2013-06-15 00:26:07 +02:00
Thomas Preud'homme
f6b50558fc Add support for load/store of _Bool value
Add support for loading _Bool value in i386, x86_64 and arm as well as
support for storing _Bool value on arm.
2013-06-14 16:19:51 +02:00
Roy
807dc7c8de tccpe: pstrcpy() will truncate .stabstr section name, use strncpy() instead. 2013-06-06 09:26:31 +08:00
Thomas Preud'homme
d0c4138ac2 Improve texi2html -> makeinfo conversion 2013-05-29 13:16:54 +02:00
Fabrice Bellard
47d9f08c6f Relicensing TinyCC 2013-05-23 10:40:12 +02:00
Shinichiro Hamaji
47305d427d Relicensing TinyCC 2013-05-06 06:55:16 +09:00
Thomas Preud'homme
6f512a7f1c Relicensing TinyCC 2013-05-05 23:51:58 +02:00
grischka
e670435500 Relicensing TinyCC
It has been discussed on the list whether it would be good
to relicense TinyCC under a more permissive BSD-like license.

The discussion started here:
http://lists.gnu.org/archive/html/tinycc-devel/2013-04/msg00052.html

Opinions varied but mostly were positive so it appears to
be worth to start the process and see how far we can get.

For that purpose I've committed a new file RELICENSING with the
suggested new license clause and a list for people to confirm
their agreement (or disagreement).

If you have contributed to TinyCC in the past, in particular if
you are one of the copyright owners for an entire file, please
add yourself to that file (rsp. replace the question mark) and
commit the change to the "mob" brancn with log message:

     Relicensing TinyCC

Thanks.
2013-05-05 23:45:51 +02:00
Daniel Glöckner
4d86b20701 ARM hardfloat: fix struct return with float/double args
Fixes the case where the structure is not returned in registers.
2013-05-01 16:17:54 +02:00
grischka
be1b6ba7b7 avoid "decl after statement" please
for compiling tcc with msc
2013-04-30 00:33:34 +02:00
James Lyon
41b3c7a507 Improved variable length array support.
VLA storage is now freed when it goes out of scope. This makes it
possible to use a VLA inside a loop without consuming an unlimited
amount of memory.

Combining VLAs with alloca() should work as in GCC - when a VLA is
freed, memory allocated by alloca() after the VLA was created is also
freed. There are some exceptions to this rule when using goto: if a VLA
is in scope at the goto, jumping to a label will reset the stack pointer
to where it was immediately after the last VLA was created prior to the
label, or to what it was before the first VLA was created if the label
is outside the scope of any VLA. This means that in some cases combining
alloca() and VLAs will free alloca() memory where GCC would not.
2013-04-27 22:58:52 +01:00
James Lyon
6ee366e765 Fixed x86-64 long double passing.
long double arguments require 16-byte alignment on the stack, which
requires adjustment when the the stack offset is not an evven number of
8-byte words.
2013-04-26 16:42:12 +01:00
James Lyon
41d76e1fcb Fixed silly error in Windows build of tests (abitest-cc not linking to libtcc)
I really should do this when less tired; I keep breaking one platform
while fixing another. I've also fixed some Windows issues with tcctest
since Windows printf() uses different format flags to those on Linux,
and removed some conditional compilation tests in tcctest since they
now should work.
2013-04-26 01:27:04 +01:00
James Lyon
ae2ece93da Fixed i386 calling convention issue and CMake build on i386.
The i386 calling convention expects the callee to pop 1 word of the
stack when performing a struct ret.
2013-04-26 00:31:46 +01:00
James Lyon
1caee8ab3b Sorted out CMake on x86-64 and fixed silly XMM# bug introduced when working on Win64 stdargs.
I removed the XMM6/7 registers from the register list because they are not used
on Win64 however they are necessary for parameter passing on x86-64. I have now
restored them but not marked them with RC_FLOAT so they will not be used except
for parameter passing.
2013-04-25 22:30:53 +01:00
James Lyon
e7a7efed11 Added cross compilation to CMake build system.
Brings it more into line with make based system. I've tested on 32- and 64-bit
Windows, but not yet Linux.
2013-04-25 01:08:18 +01:00
James Lyon
5c35ba66c5 64-bit tests now pass (well, nearly).
tcctest1-3 fail, but this appears to be due to bugs in GCC rather than TCC
(from manual inspection of the output).
2013-04-24 02:19:15 +01:00
James Lyon
8a81f9e103 Added CMake build system (to facilitate Win64 builds)
Win32 build and tests work under CMake, however I haven't added
install code yet. Win64 build fails due to chkstk.S failing to
assemble.
2013-04-21 11:20:20 +01:00
James Lyon
05fa2e754b Workaround for MinGWs use of 80-bit long double on Win32.
This is incompatible with MSVC and TCC on Win32.

Bounds checking appears to be broken (test4).
2013-04-19 23:21:33 +01:00
James Lyon
23f73e92f3 Fixed 64-bit integer bug introduced by x86-64 ABI work.
Now I need to check that the x86-64 stuff still works.
2013-04-19 22:55:09 +01:00
James Lyon
cbce6d2bac Improved x86-64 XMM register argument passing.
Also made XMM0-7 available for use as temporary registers, since they
are not used by the ABI. I'd like to do the same with RSI and RDI but
that's trickier since they can be used by gv() as temporary registers
and there isn't a way to disable that.
2013-04-19 22:05:49 +01:00
James Lyon
946afd2343 Fixed problems with XMM1 use on Linux/x86-64.
All tests pass. I think I've caught all the cases assuming only XMM0 is
used. I expect that Win64 is horribly broken by this point though,
because I haven't altered it to cope with XMM1.
2013-04-19 18:33:30 +01:00
James Lyon
0e17671f72 Most x86-64 tests now work; only on error in test1-3.
I've had to introduce the XMM1 register to get the calling convention
to work properly, unfortunately this has broken a fair bit of code
which assumes that only XMM0 is used.
2013-04-19 15:33:16 +01:00
James Lyon
b961ba5396 Got test1-3 working on x86-64.
There are probably still issues on x86-64 I've missed.
I've added a few new tests to abitest, which fail (2x long long and 2x double
in a struct should be passed in registers).
2013-04-19 11:10:13 +01:00
James Lyon
55ea6d3fc1 x86-64 ABI fixes.
abitest now passes; however test1-3 fail in init_test. All other tests
pass. I need to re-test Win32 and Linux-x86.

I've added a dummy implementation of gfunc_sret to c67-gen.c so it
should now compile, and I think it should behave as before I created
gfunc_sret.
2013-04-19 00:46:49 +01:00
James Lyon
3f1d900007 Added some additional tests to abitest.c
This is just to ensure that I haven't (and don't) really mess anything up.
2013-04-18 17:55:00 +01:00
James Lyon
2bbfaf436f Tests in abitest.c now work on Win32.
I expect that Linux-x86 is probably fine. All other architectures
except ARM are definitely broken since I haven't yet implemented
gfunc_sret for these, although replicating the current behaviour
should be straightforward.
2013-04-18 17:27:34 +01:00
James Lyon
ce5e12c2f9 Added ABI compatibility tests with native compiler using libtcc.
Only one test so far, which fails on Windows (with MinGW as the native
compiler - I've tested the MinGW output against MSVC and it appears the
two are compatible).

I've also had to modify tcc.h so that tcc_set_lib_path can point to the
directory containing libtcc1.a on Windows to make the libtcc dependent
tests work. I'm not sure this is the right way to fix this problem.
2013-04-17 21:52:44 +01:00
James Lyon
e31579b076 Fixed tests on Windows (including out-of-tree problems)
Modified tcctest.c so that it uses 'double' in place of 'long double'
with MinGW since this is what TCC does, and what Visual C++ does. Added
an option -norunsrc to tcc to allow argv[0] to be set independently of
the compiled source when using tcc -run, which allows tests that rely on
the value of argv[0] to work in out-of-tree builds.

Also added Makefile rules to automatically update out-of-tree build
Makefiles when in-tree Makefiles have changed.
2013-04-17 20:32:07 +01:00
James Lyon
1d673cbfd6 Fixed out of tree build problem on Windows.
Some files installed are not generated so need to be copied from the
source tree rather than the build tree.

I also switched texi2html for makeinfo --html since texi2html is
apparently unmaintained.
2013-04-17 17:32:18 +01:00
Thomas Preud'homme
1ef95ea342 Fix building instruction wrt make/gmake
Revert building instruction to mention the use of make instead of gmake
but add a note to tell FreeBSD and OSX users to use gmake instead of
make.
2013-04-08 23:26:27 +02:00
Jov
0de6fe6c41 Update README,add x86_64/arm,FreeBSD/OSX etc.
Change make to gmake because make will not be gnu make in some OS like
FreeBSD
2013-03-25 22:51:52 +08:00
Thomas Preud'homme
c68af2db9d Fix synchronization between data and instr caches 2013-03-19 14:03:15 +01:00
Thomas Preud'homme
6ed6a36a51 Flush caches before -running program
On some architectures, ARM for instance, the data and instruction caches
are not coherent with each other. This is a problem for the -run feature
since instructions are written in memory, and are thus written in the
data cache first and then later flushed to the main memory. If the
instructions are executed before they are pushed out of the cache, then
the processor will fetch the old content from the memory and not the
newly generated code. The solution is to flush from the data cache all
the data in the memory region containing the instructions and to
invalidate the same region in the instruction cache.
2013-03-18 10:08:39 +01:00
Thomas Preud'homme
d9dfd9cded Fix configure script on FreeBSD
* x86-64 architectures are reported as amd64 by uname -r
* FreeBSD platform don't need -ldl for linking
2013-03-14 18:15:32 +01:00
Thomas Preud'homme
c219a53402 Update .gitignore with regards to test changes 2013-03-11 22:32:28 +01:00
Urs Janssen
243c699009 document $CPATH, $C_INCLUDE_PATH, $LIBRARY_PATH 2013-02-20 14:23:44 +01:00
Urs Janssen
183b2ab14c don't confuse LD_LIBRARY_PATH (run time) with LIBRARY_PATH (link time) 2013-02-19 14:41:58 +01:00
Andrew Aladjev
0ad857c80e added CPATH, C_INCLUDE_PATH and LD_LIBRARY_PATH 2013-02-19 14:47:36 +03:00
Urs Janssen
0db7f616ad remove doubled prototype
fix documentation about __TINYC__
define __STDC_HOSTED__ like __STDC__
2013-02-18 15:44:18 +01:00
Thomas Preud'homme
5d6cfe855a Fix GNU Hurd interpreter path 2013-02-18 11:53:00 +01:00
Thomas Preud'homme
e946c3583f Add support for KfreeBSD 64bits 2013-02-18 11:42:49 +01:00
Roy
322743eef8 libtcc: tcc_define_symbol() uses strings, fix segfault 2013-02-18 08:32:03 +08:00
Thomas Preud'homme
3ad64ffe2e Define __STDC_HOSTED__ to a sane value
Define __STDC_HOSTED__ to one as the correct values should be either 1
or 0. Since tinycc is hosted, it should be set to 1.

Thanks Christian Jullien for the report.
2013-02-17 22:13:41 +01:00
Thomas Preud'homme
fe64a4d005 Define __STDC_HOSTED__
Quoting Michael Matz on tinycc-devel:

"__STDC_HOSTED__  : not set (incorrectly, it should probably be set to 1
                    given that tcc assumes a normal main() and that the
                    rest of the provided facilities is provided by the C
                    library not under tcc control)"
2013-02-17 19:44:55 +01:00
Urs Janssen
0bdbd49eac add version number to manpage
avoid c++/c99 style comments in preprocessor directives
avoid leadings whitespaces in preprocessor directives
mention implemented variable length arrays in documentation
fixed ambiguous option in texi2html call (Austin English)
2013-02-17 00:48:51 +01:00
Thomas Preud'homme
d5e22108a0 Release TinyCC 0.9.26 2013-02-15 14:23:58 +01:00
Urs Janssen
bfde339b8c fixed pasto in in 108b2876; background for the additional $CC test is:
GCC_MAJOR may be set even is $CC not realy gcc (but i.e. clang, which (as
of 3.1) requires an addtional CFLAG to accept the non portable (gnuisms all
over the place; try to cimpile tcc with Sun^HOracle, Intel, Pathscale, ...
compiler) code).
2013-02-15 13:04:39 +01:00
Urs Janssen
cec76c8b8a - document -dumpversion
- fixed a broken prototype
2013-02-15 12:48:33 +01:00
Urs Janssen
108b287665 - don't use GCC_MAJOR to see if we're not using gcc as GCC_MAJOR might be set
during configure even with --cc=notgcc as long as gcc is installed.
2013-02-15 00:53:33 +01:00
Thomas Preud'homme
0928761257 Revert "Don't search libgcc_s.so.1 on /lib64"
This reverts commit b9f089fc4a.
2013-02-14 23:52:11 +01:00
grischka
c4397b2b02 configure: detect ARM variants
Using gnu make's variable variable-names.
2013-02-14 21:15:56 +01:00
Thomas Preud'homme
b9f089fc4a Don't search libgcc_s.so.1 on /lib64
It seems libgcc_s.so.1 is systematically on /lib/ (whether
/lib/$triplet for multiarch systems or just /lib for other systems).
2013-02-14 18:05:55 +01:00
grischka
762a43877b configure: pass CONFIG_xxxDIR/PATH options via commandline
- except for CONFIG_SYSROOT and CONFIG_TCCDIR

Strictly neccessary it is only for CONFIG_MULTIARCHDIR
because otherwise if it's in config.h it is impossible to
leave it undefined.

But it is also nicer not to use these definitions for
cross-compilers.

- Also:
lib/Makefile : include ../Makefile for CFLAGS
lib/libtcc1.c : fix an issue compiling tcc with tcc on x64
2013-02-14 17:43:24 +01:00
Thomas Preud'homme
99b801dafc Add missing heading slash to detect /lib64 systems 2013-02-14 16:57:27 +01:00
Thomas Preud'homme
b4656f3191 Add arm ABI detection in conftest.c 2013-02-14 16:40:16 +01:00
Thomas Preud'homme
b1a8233562 Another attempt to "detect" multiarch 2013-02-14 15:39:35 +01:00
Urs Janssen
062efe6ab8 - make clang accept unportable code in libtcc1.c
- add -dumpversion cmd.line opt
2013-02-14 08:24:51 +01:00
grischka
944627c479 configure: cleanup
- add quotes: eval opt=\"$opt\"
- use $source_path/conftest.c for OOT build
- add fn_makelink() for OOT build
- do not check lddir etc. on Windows/MSYS
- formatting

config-print.c
- rename to conftest.c (for consistency)
- change option e to b
- change output from that from "yes" to "no"
- remove inttypes.h dependency
- simpify version output

Makefile:
- improve GCC warning flag checks

tcc.h:
- add back default CONFIG_LDDIR
- add default CONFIG_TCCDIR also (just for fun)

tccpp.c:
- fix Christian's last warning
  tccpp.c: In function ‘macro_subst’:
  tccpp.c:2803:12: warning: ‘*((void *)&cval+4)’ is used uninitialized
     in this function [-Wuninitialized]
  That the change fixes the warning doesn't make sense but anyway.

libtcc.c:
- tcc_error/warning: print correct source filename/line for
  token :paste: (also inline :asm:)

lddir and multiarch logic still needs fixing.
2013-02-14 06:53:07 +01:00
Thomas Preud'homme
e298f60838 Create config-print program to test $cc
Create a helper program called config-print to print informations
relative to the BUILD/HOST environment in the case of native
compilation.
2013-02-13 22:35:36 +01:00
Thomas Preud'homme
a4cbd9b002 Various fixes for f9ac2013 2013-02-13 22:28:41 +01:00
Thomas Preud'homme
f9ac201377 Detect multiarch triplet and lddir from ldd output 2013-02-13 20:14:13 +01:00
Thomas Preud'homme
af4b27f0fd Fix previous commit
Fix commit f6cfaa6d25
2013-02-13 17:58:58 +01:00
Thomas Preud'homme
f6cfaa6d25 Improve multiarch detection
* Detect multiarch at configure time
* Detect based on the place where crti.o is
* Define multiarch triplet in tcc.h
2013-02-13 17:03:30 +01:00
grischka
05108a3b0a libtcc: new LIBTCCAPI tcc_set_options(TCCState*, const char*str)
This replaces       -> use instead:
-----------------------------------
- tcc_set_linker    -> tcc_set_options(s, "-Wl,...");
- tcc_set_warning   -> tcc_set_options(s, "-W...");
- tcc_enable_debug  -> tcc_set_options(s, "-g");

parse_args is moved to libtcc.c (now tcc_parse_args).

Also some cleanups:
- reorder TCCState members
- add some comments here and there
- do not use argv's directly, make string copies
- use const char* in tcc_set_linker
- tccpe: use fd instead of fp

tested with -D MEM_DEBUG: 0 bytes left
2013-02-12 19:13:28 +01:00
grischka
829655949b tcc --help: update option summary
tcc-doc.texi: also
2013-02-10 20:39:05 +01:00
grischka
8042121d74 tcc -vv/--print-search-dirs: print more info
tests/Makefile:
- print-search-dirs when 'hello' fails
- split off hello-run

win32/include/_mingw.h:
- fix for compatibility with mingw headers
  (While our headers in win32 are from mingw-64 and don't have
  the problem)

tiny_libmaker:
- don't use "dangerous" mktemp
2013-02-10 00:38:40 +01:00
grischka
d6d7686b60 tcc.h: declare CValue.tab[LDOUBLE_SIZE/4]
Should fix some warnings wrt. access out of array bounds.

tccelf.c: fix "static function unused" warning
x86_64-gen.c: fix "ctype.ref uninitialzed" warning and cleanup
tcc-win32.txt: remove obsolete limitation notes.
2013-02-08 19:07:11 +01:00
Thomas Preud'homme
4b8e7f1f39 Fix fn_dirname in configure script
Use ${parameter%word} construct to fix fn_dirname in configure script.
Bonus: on less fork.
2013-02-08 11:07:22 +01:00
grischka
7a477d70ca lib/Makefile: use CC, add bcheck to libtcc1.a
Also:
- fix "make tcc_p" (profiling version)
- remove old gcc flags:
  -mpreferred-stack-boundary=2 -march=i386 -falign-functions=0
- remove test "hello" for Darwin (cannot compile to file)
2013-02-06 19:01:07 +01:00
grischka
92024ab07a tccelf: fix debug section relocation
With:
   tcc -g hello.c
   gdb a.out
     b main
gdb refused to know "main" because of broken dwarf info.

This partially reverts commit 0d598aca08.
I don't remember what the problem was but it was the wrong way
to fix it.
2013-02-05 21:18:29 +01:00
grischka
d5f4df09ff tests: cleanup
tests:
- add "hello" to test first basic compilation to file/memory
- add "more" test (tests2 suite)
- remove some tests

tests2:
- move into tests dir
- Convert some files from DOS to unix LF
- remove 2>&1 redirection

win32:
- tccrun.c: modify exception filter to exit correctly (needed for btest)
- tcctest.c: exclude weak_test() (feature does not exist on win32)
2013-02-05 14:27:38 +01:00
grischka
60cf64612c tests2: move into tests 2013-02-05 13:22:36 +01:00
Thomas Preud'homme
6c4d3244da Align on 4n bytes when copying fct args on stack
When copying function arguments on stack in prolog, use multiple of 4
bytes for alignment.
2013-02-05 10:48:42 +01:00
grischka
e0aee4f455 portability: make tcc_get_symbol() available for non-native
For consistency with tcc_add_symbol().
Use uintptr_t here also.
2013-02-04 20:57:57 +01:00
Thomas Preud'homme
60e647f856 Slightly improved support for !gcc compilers
Hack before a complete solution after 0.9.26's release to be able to
compile tcc with clang.
2013-02-04 18:14:06 +01:00
grischka
248dc67506 win32: Honor "-Wl,-subsystem=console/gui" option 2013-02-04 17:58:37 +01:00
grischka
4b539aa67d tccrun.c: unify rt_get_caller_pc prototype 2013-02-04 17:24:03 +01:00
grischka
97c279f5ea Makefile: fix "allow CONFIG_LDDIR=lib64 configuration"
I forgot the commas.
2013-02-04 17:10:47 +01:00
grischka
82bcbd027f portability: fix void* <-> target address conversion confusion
- #define addr_t as ElfW(Addr)
- replace uplong by addr_t
- #define TCC_HAS_RUNTIME_PLTGOT and use it
2013-02-04 16:24:59 +01:00
grischka
3186455599 Makefile: allow CONFIG_LDDIR=lib64 configuration 2013-02-04 16:24:58 +01:00
grischka
4c2941d248 win32: wincrt1.c: include stdlib.h for exit() 2013-02-04 16:24:57 +01:00
grischka
263dc93cfa c67: remove global #define's for TRUE/FALSE/BOOL
Also use uppercase TRUE/FALSE instead of true/false
2013-02-04 16:24:56 +01:00
Thomas Preud'homme
f715207249 arm-gen.c: fix var initialization in gfunc_call
Fix initialization of args_size before doing register allocation.
When adding hardfloat calling convention the initialization stopped
being performed when !defined (TCC_ARM_EABI).
2013-02-04 11:01:58 +01:00
Daniel Glöckner
61a4fd1d6e arm: force rounding towards zero on cast to integer with VFP
Cast to integer should not be affected by the current rounding mode
as set by fesetround.
2013-02-04 09:17:01 +01:00
Daniel Glöckner
f7f6025bd1 arm: fix conversion from float/double to signed integer with VFP
The signed flag was not encoded in the instruction.
2013-02-03 23:47:52 +01:00
Daniel Glöckner
506193724f arm: fix conversion from integer to float/double with VFP
The source register was not encoded in the instruction.
2013-02-03 17:51:33 +01:00
Thomas Preud'homme
6f4983af5b Revert "Add predictability in CType initialization."
This reverts commit 93785149ed.
2013-01-31 13:43:04 +01:00
Thomas Preud'homme
ae33c30b49 Revert "Don't call elf_hash on NULL value"
This reverts commit 505329b5b3.
2013-01-31 13:43:04 +01:00
grischka
2f6b8469cc safety: replace occurrences of strcpy by pstrcpy 2013-01-31 13:23:19 +01:00
Thomas Preud'homme
370547a550 Revert "Check whether structure fields have a type"
This reverts commit 981eb84d8a.
2013-01-31 13:02:04 +01:00
Thomas Preud'homme
981eb84d8a Check whether structure fields have a type 2013-01-31 12:32:31 +01:00
Domingo Alvarez Duarte
505329b5b3 Don't call elf_hash on NULL value
Make sur elf_hash is never invoked with a NULL value.

Signed-off-by: Thomas Preud'homme <robotux@celest.fr>
2013-01-31 12:07:20 +01:00
Domingo Alvarez Duarte
93785149ed Add predictability in CType initialization.
Initialize the ref field to 0 when manipulating a CType.

Signed-off-by: Thomas Preud'homme <robotux@celest.fr>
2013-01-31 12:04:10 +01:00
Thomas Preud'homme
1b1e7ee1fd Fix cross-compilation out-of-tree build
Add tcc.c as a prerequesite of the %-tcc$(EXESUF) target and compile $<
instead of tcc.c to make sure tcc.c is search in directories specified
by VPATH.
2013-01-30 19:39:29 +01:00
grischka
913cd6270b Changelog: cleanup 2013-01-30 18:50:02 +01:00
grischka
828ccde9fc arm: define TCC_ARM_VERSION for cross compiler 2013-01-30 18:39:36 +01:00
grischka
b7e75ccdb0 tccpe: no debug, no stabs 2013-01-30 18:39:26 +01:00
grischka
17cf0dcf70 configure: use relative paths for in-tree build
Also
- move CPPFLAGS to Makefile
- Use top_srcdir in lib/Makefile
2013-01-30 18:39:09 +01:00
Thomas Preud'homme
6ccee6edb3 Add my copyright for changes in arm-gen.c 2013-01-30 17:34:19 +01:00
Thomas Preud'homme
5fa135f9eb Changelog update 2013-01-30 17:13:40 +01:00
Thomas Preud'homme
01e1eecdbe Update Changelog 2013-01-30 17:07:18 +01:00
Thomas Preud'homme
52947e5844 Favor arm hardfloat over arm softfloat.
Favor ARM hardfloat over ARM softfloat calling convention. In
particular, this solve the problem of the raspbian distribution where
the softfloat ld.so pathname (lib/ld-linux.so.3) is actually a symlink
to the hardfloat ld.so pathname (/lib/arm-linux-gnueabihf/ld-2.13.so).
2013-01-29 18:15:23 +01:00
Thomas Preud'homme
bcac413c30 Fix overflow detection in ARM relocation
Fix overflow detection for R_ARM_CALL, R_ARM_PC24, R_ARM_JUMP24 and
R_ARM_PLT32 relocations on ARM. 26 bits means 25 bits for positive and
negative offsets !
2013-01-28 19:13:25 +01:00
Thomas Preud'homme
0f81512d7d Fix stack alignment on 8 bytes at function call
Ensure stack pointer is correctly adjusted in prolog to be aligned on 8
bytes after the change of frame linking.
2013-01-27 01:08:01 +01:00
Thomas Preud'homme
f3e5649150 Don't do builtin_frame_address test with ARM gcc
gcc fails the builtin_frame_address test on ARM so we disable it. As a
consequence, the diff between gcc and tcc's output is unecessarily
bigger. Given the big size of the diff currently, this doesn't make a
big difference but may allow to detect a regression in tcc's
implementation of builtin_frame_address.
2013-01-26 20:31:14 +01:00
Thomas Preud'homme
f63c750942 Organize frames in a real linked list on ARM
Change the linking of the frames on ARM. Instead of having fp points 12
bytes above where the old fp is stored, let fp points where the old fp
is stored. That is, we switch from:

|   .    |
|   .    |
|   .    |
|        |
| params | <-- fp
 --------
| oldlr  |
 --------
| oldip  |
 --------
| oldfp  |
 --------

to:

|   .    |
|   .    |
|   .    |
|        |
| params |
 --------
| oldlr  |
 --------
| oldip  |
 --------
| oldfp  | <-- fp
 --------
2013-01-26 20:09:04 +01:00
Thomas Preud'homme
de35a3389f Use gcc to generate tcctest.gcc 2013-01-25 20:14:10 +01:00
Thomas Preud'homme
f8cde52984 Link STT_GNU_IFUNC into STT_FUNC in executable.
Indirect functions shall have STT_FUNC type in executable dynsym
section. Indeed, a dlsym call following a lazy resolution would pick the
symbol value from the executable dynsym entry. This would contain the
address of the function wanted by the caller of dlsym instead of the
address of the function that would return that address.
2013-01-25 20:06:51 +01:00
grischka
b89793d10a win32: _mingw.h: do not undef NULL
Not wise if stddef.h was already included. This is related to commit

    3aa26a794e

Instead hack stddef.h to have identical definition and thus
avoid the issue mentionned there.
2013-01-24 19:49:58 +01:00
Thomas Preud'homme
6b6eea60f3 Fix [f]getc return value usage in 40_stdio test
Store [f]getc return value into an int instead of char, as per
prototype. This fix an issue when char is unsigned (as is on arm for
both tcc and gcc).
2013-01-24 10:55:18 +01:00
grischka
c5892fe4f5 Revert "Optimize vswap()"
This reverts commit 63193d1794.

Had some problems (_STATIC_ASSERT) and was too ugly anyway.
For retry, I'd suggest to implement a general function
    static inline void memswap (void *p1, void* p2, size_t n);
and then use that.  If you do so, please keep the original code
as comment.
2013-01-14 18:41:37 +01:00
grischka
2daf8b96a8 Revert mistake in "win32: malloc.h: fix win32 ... _STATIC_ASSERT"
from commit fc574f1498.

The files from include are copied to win32/include with make
install or build-tcc.bat.
2013-01-14 18:41:36 +01:00
Thomas Preud'homme
f7b417723e Fix out-of-tree build with relative path to root
Fix path of Makefile symlinks in a out-of-tree build where the root
directory of the source is given as a relative path.
2013-01-14 18:18:27 +01:00
Thomas Preud'homme
a4e630c7d9 Install libtcc.h when invoking make install
This fix commit e79281f58e
2013-01-14 18:16:17 +01:00
Thomas Preud'homme
8c56b0cf90 Revert "Added what I call virtual io to tinycc this way we can make a monolitic executable or library that contains all needed to compile programs, truly tinycc portable."
This reverts commit 59e18aee0e.
tcc is being stabilized now in order to do a new release soon.
Therefore, such a change is not appropriate now.
2013-01-14 17:34:07 +01:00
Thomas Preud'homme
60a3ff5f2c Revert "pe: fix tcc not linking to user32 and gdi32"
This reverts commit 943574aba5.
The empty string in "libs" was intended behavior, as can be seen from
the "if (0 == *p)" below.
2013-01-14 17:21:06 +01:00
Thomas Preud'homme
5e7954b408 Stop setting -Wno-unused-result switch in Makefile
This commit revert commit 061b5799cc and
subsequent commits to detect whether -Wno-unused-result is supported or
not by the compiler used to compile tcc. No warning about unused results
is issued in a normal build and thus this switch is only needed if
calling make with extra switches in CFLAGS or CPPFLAGS. It should thus
be added with the extra switches when calling make and not in the
Makefile.
2013-01-13 23:38:33 +01:00
Thomas Preud'homme
ea583f7b8a Fix C99ism in vswap()
Declare vtopl in vswap at the beginning of the function before any
assignments. Doing otherwise means C99 is assumed when compiling.
2013-01-13 23:38:33 +01:00
mingodad
59e18aee0e Added what I call virtual io to tinycc this way we can make a monolitic executable or library that contains all needed to compile programs, truly tinycc portable.
Tested under linux exec the "mk-it" shell script and you'll end up with a portable tinycc executable that doesn't depend on anything else.
2013-01-11 00:04:38 +00:00
grischka
0a8c7d143e Fix "Optimize cstr_reset() to only reset string to empty"
This fixes commit 8eb92e6052

Remove memory leak.
2013-01-06 17:21:33 +01:00
grischka
2358b378b3 tccpp: alternative fix for #include_next infinite loop bug
This replaces commit 3d409b0889

- revert old fix in libtcc.c
- #include_next: look up the file in the include stack to see
  if it is already included.
Also:
- streamline include code
- remove 'type' from struct CachedInclude (obsolete because we check
  full filename anyway)
- remove inc_type & inc_filename from struct Bufferedfile (obsolete)
- fix bug with TOK_FLAG_ENDIF not being reset
- unrelated: get rid of an 'variable potentially uninitialized' warning
2013-01-06 17:20:44 +01:00
Thomas Preud'homme
e92dbe4686 Stop returning 0 in cmp_comparison_test
cmp_comparison_test has no return value and should thus not return 0.
2013-01-06 12:26:53 +01:00
Thomas Preud'homme
eb028a8f42 Honor CC when testing for -Wno-unused-result
The compiler used for compiling tcc is the one referenced in the
CC variable. As such, the check for -Wno-unused-result presence should
be done on CC.
2013-01-06 12:22:56 +01:00
Roy
fc574f1498 win32: malloc.h: fix win32 tcc-tcc complication by correcting _STATIC_ASSERT, ideas from mingw-w64 changeset 4293
stdarg.h, stddef.h: _mingw.h needs them
2012-12-31 08:59:50 +08:00
Kirill Smelkov
63193d1794 Optimize vswap()
vswap() is called often enough and shows in profile and it was easy to
hand optimize swapping vtop[-1] and vtop[0] - instead of large (28 bytes
on i386) tmp variable and two memory to memory copies, let's swap areas
by longs through registers with streamlined assembly.

For

    $ ./tcc -B. -bench -DONE_SOURCE -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -c tcc.c

before:

 # Overhead      Command        Shared Object                                          Symbol
 # ........  ...........  ...................  ..............................................
 #
     15.19%          tcc  tcc                  [.] next_nomacro1
      5.19%          tcc  libc-2.13.so         [.] _int_malloc
      4.57%          tcc  tcc                  [.] next
      3.36%          tcc  tcc                  [.] tok_str_add2
      3.03%          tcc  tcc                  [.] macro_subst_tok
      2.93%          tcc  tcc                  [.] macro_subst
      2.53%          tcc  tcc                  [.] next_nomacro_spc
      2.49%          tcc  tcc                  [.] vswap
      2.36%          tcc  libc-2.13.so         [.] _int_free

       │    ST_FUNC void vswap(void)
       │    {
  1,96 │      push   %edi
  2,65 │      push   %esi
  1,08 │      sub    $0x20,%esp
       │        SValue tmp;
       │
       │        /* cannot let cpu flags if other instruction are generated. Also
       │           avoid leaving VT_JMP anywhere except on the top of the stack
       │           because it would complicate the code generator. */
       │        if (vtop >= vstack) {
  0,98 │      mov    0x8078cac,%eax
       │      cmp    $0x8078d3c,%eax
  1,18 │   ┌──jb     24
       │   │        int v = vtop->r & VT_VALMASK;
  1,08 │   │  mov    0x8(%eax),%edx
  0,78 │   │  and    $0x3f,%edx
       │   │        if (v == VT_CMP || (v & ~1) == VT_JMP)
  0,78 │   │  cmp    $0x33,%edx
  0,69 │   │↓ je     54
  0,59 │   │  and    $0xfffffffe,%edx
  0,49 │   │  cmp    $0x34,%edx
  0,29 │   │↓ je     54
       │   │            gv(RC_INT);
       │   │    }
       │   │    tmp = vtop[0];
  1,08 │24:└─→lea    0x4(%esp),%edi
  0,39 │      mov    $0x7,%ecx
       │      mov    %eax,%esi
 14,41 │      rep    movsl %ds:(%esi),%es:(%edi)
       │        vtop[0] = vtop[-1];
  9,51 │      lea    -0x1c(%eax),%esi
  1,96 │      mov    $0x7,%cl
       │      mov    %eax,%edi
 17,06 │      rep    movsl %ds:(%esi),%es:(%edi)
       │        vtop[-1] = tmp;
 10,20 │      mov    0x8078cac,%edi
  2,35 │      sub    $0x1c,%edi
  0,78 │      lea    0x4(%esp),%esi
       │      mov    $0x7,%cl
 15,20 │      rep    movsl %ds:(%esi),%es:(%edi)
       │    }
  9,90 │      add    $0x20,%esp
  2,25 │      pop    %esi
  1,67 │      pop    %edi
  0,69 │      ret

after:

 # Overhead      Command        Shared Object                                          Symbol
 # ........  ...........  ...................  ..............................................
 #
     15.27%          tcc  tcc                  [.] next_nomacro1
      5.08%          tcc  libc-2.13.so         [.] _int_malloc
      4.57%          tcc  tcc                  [.] next
      3.17%          tcc  tcc                  [.] tok_str_add2
      3.12%          tcc  tcc                  [.] macro_subst
      2.99%          tcc  tcc                  [.] macro_subst_tok
      2.43%          tcc  tcc                  [.] next_nomacro_spc
      2.32%          tcc  libc-2.13.so         [.] _int_free

      . . .

      0.71%          tcc  tcc                  [.] vswap

       │    ST_FUNC void vswap(void)
       │    {
  7,22 │      push   %eax
       │        /* cannot let cpu flags if other instruction are generated. Also
       │           avoid leaving VT_JMP anywhere except on the top of the stack
       │           because it would complicate the code generator. */
       │        if (vtop >= vstack) {
 11,34 │      mov    0x8078cac,%eax
  2,75 │      cmp    $0x8078d3c,%eax
  0,34 │   ┌──jb     20
       │   │        int v = vtop->r & VT_VALMASK;
  0,34 │   │  mov    0x8(%eax),%edx
  8,93 │   │  and    $0x3f,%edx
       │   │        if (v == VT_CMP || (v & ~1) == VT_JMP)
  2,06 │   │  cmp    $0x33,%edx
  2,41 │   │↓ je     74
  2,41 │   │  and    $0xfffffffe,%edx
  0,34 │   │  cmp    $0x34,%edx
  2,41 │   │↓ je     74
       │   │        vtopl[-1*VSIZEL + i] = tmpl;    \
       │   │      } do {} while (0)
       │   │
       │   │    VSWAPL(15); VSWAPL(14); VSWAPL(13); VSWAPL(12);
       │   │    VSWAPL(11); VSWAPL(10); VSWAPL( 9); VSWAPL( 8);
       │   │    VSWAPL( 7); VSWAPL( 6); VSWAPL( 5); VSWAPL( 4);
  2,06 │20:└─→mov    0x18(%eax),%edx
  1,37 │      mov    -0x4(%eax),%ecx
  2,06 │      mov    %ecx,0x18(%eax)
  1,37 │      mov    %edx,-0x4(%eax)
  2,06 │      mov    0x14(%eax),%edx
  2,06 │      mov    -0x8(%eax),%ecx
  2,41 │      mov    %ecx,0x14(%eax)
  3,09 │      mov    %edx,-0x8(%eax)
  3,09 │      mov    0x10(%eax),%edx
  1,72 │      mov    -0xc(%eax),%ecx
  2,75 │      mov    %ecx,0x10(%eax)
  1,72 │      mov    %edx,-0xc(%eax)
       │        VSWAPL( 3); VSWAPL( 2); VSWAPL( 1); VSWAPL( 0);
  2,41 │      mov    0xc(%eax),%edx
  2,41 │      mov    -0x10(%eax),%ecx
  2,41 │      mov    %ecx,0xc(%eax)
  0,69 │      mov    %edx,-0x10(%eax)
  1,72 │      mov    0x8(%eax),%edx
  0,69 │      mov    -0x14(%eax),%ecx
  1,03 │      mov    %ecx,0x8(%eax)
  1,37 │      mov    %edx,-0x14(%eax)
  1,37 │      mov    0x4(%eax),%edx
  0,69 │      mov    -0x18(%eax),%ecx
  3,09 │      mov    %ecx,0x4(%eax)
  2,06 │      mov    %edx,-0x18(%eax)
  1,37 │      mov    (%eax),%edx
  2,41 │      mov    -0x1c(%eax),%ecx
  1,37 │      mov    %ecx,(%eax)
  4,12 │      mov    %edx,-0x1c(%eax)
       │        }
       │
       │    #   undef VSWAPL
       │    #   undef VSIZEL
       │    }
  1,03 │      pop    %eax
  3,44 │      ret

Overal speedup:

    # best of 5 runs
    before: 8268 idents, 47203 lines, 1526763 bytes, 0.148 s, 319217 lines/s, 10.3 MB/s
    after:  8273 idents, 47231 lines, 1527685 bytes, 0.146 s, 324092 lines/s, 10.5 MB/s

Static ASSERT macro taken from CCAN's[1] build_assert[2] which is in
public domain.

[1] http://ccodearchive.net/
[2] http://git.ozlabs.org/?p=ccan;a=blob;f=ccan/build_assert/build_assert.h;h=24e59c44cd930173178ac9b6e101b0af64a879e9;hb=HEAD
2012-12-21 20:46:26 +04:00
Kirill Smelkov
8eb92e6052 Optimize cstr_reset() to only reset string to empty, not call free() and later malloc()
A CString could be reset to empty just setting its .size to 0.

If memory was already allocated, that would be remembered in
.data_allocated and .size_allocated and on consequent string
manipulations that memory will be used without immediate need to call
malloc().

For

    $ ./tcc -B. -bench -DONE_SOURCE -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -c tcc.c

after the patch malloc/free are called less often:

(tcc is run in loop; perf record -a sleep 10 && perf report)
before:

 # Overhead      Command       Shared Object                                      Symbol
 # ........  ...........  ..................  ..........................................
 #
     13.89%          tcc  tcc                 [.] next_nomacro1
      4.73%          tcc  libc-2.13.so        [.] _int_malloc
      4.39%          tcc  tcc                 [.] next
      2.94%          tcc  tcc                 [.] tok_str_add2
      2.78%          tcc  tcc                 [.] macro_subst_tok
      2.75%          tcc  libc-2.13.so        [.] free
      2.74%          tcc  tcc                 [.] macro_subst
      2.63%          tcc  libc-2.13.so        [.] _int_free
      2.28%          tcc  tcc                 [.] vswap
      2.24%          tcc  tcc                 [.] next_nomacro_spc
      2.06%          tcc  libc-2.13.so        [.] realloc
      2.00%          tcc  libc-2.13.so        [.] malloc
      1.99%          tcc  tcc                 [.] unary
      1.85%          tcc  libc-2.13.so        [.] __i686.get_pc_thunk.bx
      1.76%  kworker/0:1  [kernel.kallsyms]   [k] delay_tsc
      1.70%          tcc  tcc                 [.] next_nomacro
      1.62%          tcc  tcc                 [.] preprocess
      1.41%          tcc  libc-2.13.so        [.] __memcmp_ssse3
      1.38%          tcc  [kernel.kallsyms]   [k] memset
      1.10%          tcc  tcc                 [.] g
      1.06%          tcc  tcc                 [.] parse_btype
      1.05%          tcc  tcc                 [.] sym_push2
      1.04%          tcc  libc-2.13.so        [.] _int_realloc
      1.00%          tcc  libc-2.13.so        [.] malloc_consolidate

after:

 # Overhead      Command       Shared Object                                          Symbol
 # ........  ...........  ..................  ..............................................
 #
     15.26%          tcc  tcc                 [.] next_nomacro1
      5.07%          tcc  libc-2.13.so        [.] _int_malloc
      4.62%          tcc  tcc                 [.] next
      3.22%          tcc  tcc                 [.] tok_str_add2
      3.03%          tcc  tcc                 [.] macro_subst_tok
      3.02%          tcc  tcc                 [.] macro_subst
      2.59%          tcc  tcc                 [.] next_nomacro_spc
      2.44%          tcc  tcc                 [.] vswap
      2.39%          tcc  libc-2.13.so        [.] _int_free
      2.28%          tcc  libc-2.13.so        [.] free
      2.22%          tcc  tcc                 [.] unary
      2.07%          tcc  libc-2.13.so        [.] realloc
      1.97%          tcc  libc-2.13.so        [.] malloc
      1.70%          tcc  tcc                 [.] preprocess
      1.69%          tcc  libc-2.13.so        [.] __i686.get_pc_thunk.bx
      1.68%          tcc  tcc                 [.] next_nomacro
      1.59%          tcc  [kernel.kallsyms]   [k] memset
      1.55%          tcc  libc-2.13.so        [.] __memcmp_ssse3
      1.22%          tcc  tcc                 [.] parse_comment
      1.11%          tcc  tcc                 [.] g
      1.11%          tcc  tcc                 [.] sym_push2
      1.10%          tcc  tcc                 [.] parse_btype
      1.10%          tcc  libc-2.13.so        [.] _int_realloc
      1.06%          tcc  tcc                 [.] vsetc
      0.98%          tcc  libc-2.13.so        [.] malloc_consolidate

and this gains small speedup for tcc:

    # best of 5 runs
    before: 8268 idents, 47191 lines, 1526670 bytes, 0.153 s, 307997 lines/s, 10.0 MB/s
    after:  8268 idents, 47203 lines, 1526763 bytes, 0.148 s, 319217 lines/s, 10.3 MB/s
2012-12-21 20:46:26 +04:00
Akim Demaille
e79281f58e build: fix out-of-tree install
Makefile (install): Fix installation of headers.
Do not try to install twice libtcc.h, once should be enough.
2012-12-21 14:23:28 +01:00
Akim Demaille
7667a8887a build: fix out-of-tree build
* Makefile (TCC-VERSION): Use top_srcdir.
2012-12-21 14:17:23 +01:00
Akim Demaille
8adfb4a419 build: simplify the makefiles
* Makefile: use "else if" to improve readability.
2012-12-21 14:17:16 +01:00
Akim Demaille
017bbbfee1 configure: support absolete out-of-tree builds
configure: handle the case of absolute paths.
Reported by grishka.
2012-12-21 13:57:22 +01:00
Akim Demaille
d7264e0218 configure: style changes
* configure: use more here-documents.
2012-12-21 13:49:15 +01:00
Akim Demaille
ba49862de6 configure: prefer here-documents
* configure: use here-documents to improve readability and
reduce the clutter.
2012-12-21 13:47:00 +01:00
Akim Demaille
9c9ca2032b configure: style changes
* configure (case $targetos): Improve readibility.
(case $cpu): New, to improve readability compare to if + test.
2012-12-21 13:45:22 +01:00
grischka
5ebc6a964d Makefile: revamp "tar" target
- Creates release tarball from *current* git branch
- Includes tcc-doc.html
- converts important windows files files to CRLF
  (requirement for the cmd.exe batch processor, convenience for
   reading the txt in notepad)
2012-12-20 21:29:57 +01:00
grischka
b174399340 win32: build-tcc.bat: get rid of hardcoded VERSION string
Also:
 - put libtcc.def into libtcc dir
 - remove ar references
 - remove libtcc_test from build
2012-12-20 21:20:54 +01:00
Akim Demaille
3f09b90d21 build: fix VPATH builds
* configure (fn_dirname): New.
Use it to ensure the creation of proper symlinks to Makefiles.
(config.mak): Define top_builddir and top_srcdir.
(CPPFLAGS): Be sure to find the headers.
* Makefile, lib/Makefile, tests/Makefile, tests2/Makefile: Adjust
to set VPATH properly.
Fix confusion between top_builddir and top_srcdir.
2012-12-18 10:06:20 +01:00
Roy
d815896d4c bcheck: there is no unistd.h in win32. 2012-12-10 09:51:49 +08:00
Kirill Smelkov
a55ecf6d2c Repair bounds-checking more, this time tcc -b -run tcc.c -run tcc.c -run tcctest.c works
Hello up there. On the list Grischka made a point that we can't recommend using
-b as long as tcc -b tcc.c doesn't produce anything useful. Now it does, so
please don't treat -b mode as second class citizen anymore.

Thanks,
Kirill

* bcheck2:
  tests: Add tests for compile/run tcc.c with `tcc -b` then compile tcc.c again, then run tcctest.c
  lib/bcheck: Fix code typo in __bound_delete_region()
  lib/bcheck: Don't assume heap goes right after bss
  Make tcc work after self-compiling with bounds-check enabled
2012-12-09 19:51:20 +04:00
Kirill Smelkov
031ff872be tests: Add tests for compile/run tcc.c with tcc -b then compile tcc.c again, then run tcctest.c
Just like with test[123] add their test[123]b variants. After previous 3
patchs all test pass here on Debian GNU/Linux on i385 with gcc-4.7 with
or without memory randomization turned on.
2012-12-09 19:43:40 +04:00
Kirill Smelkov
dbeb4faf21 lib/bcheck: Fix code typo in __bound_delete_region()
We were calling get_page() with t2 index which is not correct, since
get_page() operate on t1 indices. The bug is here from day-1, from
60f781c4 (first version of bounds checker) and show as a crash in
__bound_delete_region() at program exit:

    $ ./tcc   -B. -DTCC_TARGET_I386 -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -b -run -DONE_SOURCE \
      ./tcc.c -B. -DTCC_TARGET_I386 -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\"    -run -DONE_SOURCE \
      ./tcc.c -B. -run tests/tcctest.c

    (lot's of correct output from tcctest)
    Runtime error: dereferencing invalid pointer
    at 0xa7c21cc4 __bound_delete_region()
    by (nil) ???
    Segmentation fault

The fix is simple - last page should be get through t1_end, like it is
done in __bound_new_region().

After this patch, tcc is being able to compile itself with -b, then
compile itself again and run tcctest with correct output. Tests follow.
2012-12-09 19:33:47 +04:00
Kirill Smelkov
efd9d92b7c lib/bcheck: Don't assume heap goes right after bss
At startup __bound_init() wants to mark malloc zone as invalid memory,
so that any access to memory on heap, not allocated through malloc be
invalid. Other pages are initialized as empty regions, access to which
is not treated as invalid by bounds-checking.

The problem is code incorrectly assumed that heap goes right after bss,
and that is not correct for two cases:

    1) if we are running from `tcc -b -run`, program text data and bss
       will be already in malloced memory, possibly in mmaped region
       insead of heap, and marking memory as invalid from _end
       will not cover heap and probably wrongly mark correct regions.

    2) if address space randomization is turned on, again heap does not
       start from _end, and we'll mark as invalid something else instead
       of malloc area.

For example with the following diagnostic patch ...

    diff --git a/tcc.c b/tcc.c
    index 5dd5725..31c46e8 100644
    --- a/tcc.c
    +++ b/tcc.c
    @@ -479,6 +479,8 @@ static int parse_args(TCCState *s, int argc, char **argv)
         return optind;
     }

    +extern int _etext, _edata, _end;
    +
     int main(int argc, char **argv)
     {
         int i;
    @@ -487,6 +489,18 @@ int main(int argc, char **argv)
         int64_t start_time = 0;
         const char *default_file = NULL;

    +    void *brk;
    +
    +    brk = sbrk(0);
    +
    +    fprintf(stderr, "\n>>> TCC\n\n");
    +    fprintf(stderr, "etext:\t%10p\n",  &_etext);
    +    fprintf(stderr, "edata:\t%10p\n",  &_edata);
    +    fprintf(stderr, "end:\t%10p\n",    &_end);
    +    fprintf(stderr, "brk:\t%10p\n",    brk);
    +    fprintf(stderr, "stack:\t%10p\n",  &brk);
    +
    +    fprintf(stderr, "&errno: %p\n", &errno);
         s = tcc_new();

         output_type = TCC_OUTPUT_EXE;

    diff --git a/tccrun.c b/tccrun.c
    index 531f46a..25ed30a 100644
    --- a/tccrun.c
    +++ b/tccrun.c
    @@ -91,6 +91,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
         int (*prog_main)(int, char **);
         int ret;

    +    fprintf(stderr, "\n\ntcc_run() ...\n\n");
    +
         if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
             return -1;

    diff --git a/lib/bcheck.c b/lib/bcheck.c
    index ea5b233..8b26a5f 100644
    --- a/lib/bcheck.c
    +++ b/lib/bcheck.c
    @@ -296,6 +326,8 @@ static void mark_invalid(unsigned long addr, unsigned long size)
         start = addr;
         end = addr + size;

    +    fprintf(stderr, "mark_invalid  %10p - %10p\n", (void *)addr, (void *)end);
    +
         t2_start = (start + BOUND_T3_SIZE - 1) >> BOUND_T3_BITS;
         if (end != 0)
             t2_end = end >> BOUND_T3_BITS;

... Look how memory is laid out for `tcc -b -run ...`:

    $ ./tcc -B. -b -DTCC_TARGET_I386 -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\"  -run   \
        -DONE_SOURCE ./tcc.c -B. -c x.c

    >>> TCC

    etext:   0x8065477
    edata:   0x8070220
    end:     0x807a95c
    brk:     0x807b000
    stack:  0xaffff0f0
    &errno: 0xa7e25688

    tcc_run() ...

    mark_invalid  0xfff80000 -      (nil)
    mark_invalid  0xa7c31d98 - 0xafc31d98

    >>> TCC

    etext:  0xa7c22767
    edata:  0xa7c2759c
    end:    0xa7c31d98
    brk:     0x8211000
    stack:  0xafffeff0
    &errno: 0xa7e25688
    Runtime error: dereferencing invalid pointer
    ./tccpp.c:1953: at 0xa7beebdf parse_number() (included from ./libtcc.c, ./tcc.c)
    ./tccpp.c:3003: by 0xa7bf0708 next() (included from ./libtcc.c, ./tcc.c)
    ./tccgen.c:4465: by 0xa7bfe348 block() (included from ./libtcc.c, ./tcc.c)
    ./tccgen.c:4440: by 0xa7bfe212 block() (included from ./libtcc.c, ./tcc.c)
    ./tccgen.c:5529: by 0xa7c01929 gen_function() (included from ./libtcc.c, ./tcc.c)
    ./tccgen.c:5767: by 0xa7c02602 decl0() (included from ./libtcc.c, ./tcc.c)

The second mark_invalid goes right after in-memory-compiled program's
_end, and oops, that's not where malloc zone is (starts from brk), and oops
again, mark_invalid covers e.g. errno. Then compiled tcc is crasshing by
bcheck on errno access:

    1776 static void parse_number(const char *p)
    1777 {
    1778     int b, t, shift, frac_bits, s, exp_val, ch;
         ...
    1951             *q = '\0';
    1952             t = toup(ch);
    1953             errno = 0;

The solution here is to use sbrk(0) as approximation for the program
break start instead of &_end:

    - if we are a separately compiled program, __bound_init() runs early,
      and sbrk(0) should be equal or very near to start_brk (in case other
      constructors malloc something), or

    - if we are running from under `tcc -b -run`, sbrk(0) will return
      start of heap portion which is under this program control, and not
      mark as invalid earlier allocated memory.

With this patch `tcc -b -run tcc.c ...` succeeds compiling above
small-test program (diagnostic patch is still applied too):

    $ ./tcc -B. -b -DTCC_TARGET_I386 -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\"  -run   \
        -DONE_SOURCE ./tcc.c -B. -c x.c

    >>> TCC

    etext:   0x8065477
    edata:   0x8070220
    end:     0x807a95c
    brk:     0x807b000
    stack:  0xaffff0f0
    &errno: 0xa7e25688

    tcc_run() ...

    mark_invalid  0xfff80000 -      (nil)
    mark_invalid   0x8211000 - 0x10211000

    >>> TCC

    etext:  0xa7c22777
    edata:  0xa7c275ac
    end:    0xa7c31da8
    brk:     0x8211000
    stack:  0xafffeff0
    &errno: 0xa7e25688

    (completes ok)

but running `tcc -b -run tcc.c -run tests/tcctest.c` sigsegv's - that's
the plot for the next patch.
2012-12-09 19:05:36 +04:00
Kirill Smelkov
43a11a7ed1 Make tcc work after self-compiling with bounds-check enabled
For vstack Fabrice used the trick to initialize vtop to &vstack[-1], so
that on first push, vtop becomes &vstack[0] and a value is also stored
there - everything works.

Except that when tcc is compiled with bounds-checking enabled, vstack - 1
returns INVALID_POINTER and oops...

Let's workaround it with artificial 1 vstack slot which will not be
used, but only serve as an indicator that pointing to &vstack[-1] is ok.

Now, tcc, after being self-compiled with -b works:

    $ ./tcc -B. -o tccb  -DONE_SOURCE -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" tcc.c  -ldl
    $ cd tests
    $ ../tcc -B.. -run tcctest.c >1
    $ ../tccb -B.. -run tcctest.c >2
    $ diff -u 1 2

and note, tcc's compilation speed is not affected:

    $ ./tcc -B. -bench -DONE_SOURCE -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -c tcc.c

    before: 8270 idents, 47221 lines, 1527730 bytes, 0.152 s, 309800 lines/s, 10.0 MB/s
    after:  8271 idents, 47221 lines, 1527733 bytes, 0.152 s, 310107 lines/s, 10.0 MB/s

But note, that `tcc -b -run tcc` is still broken - for example it crashes
on
    $ cat x.c
    double get100 () { return 100.0; }

    $ ./tcc -B. -b -DTCC_TARGET_I386 -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\"  -run   \
        -DONE_SOURCE ./tcc.c -B. -c x.c
    Runtime error: dereferencing invalid pointer
    ./tccpp.c:1953: at 0xa7beebdf parse_number() (included from ./libtcc.c, ./tcc.c)
    ./tccpp.c:3003: by 0xa7bf0708 next() (included from ./libtcc.c, ./tcc.c)
    ./tccgen.c:4465: by 0xa7bfe348 block() (included from ./libtcc.c, ./tcc.c)
    ./tccgen.c:4440: by 0xa7bfe212 block() (included from ./libtcc.c, ./tcc.c)
    ./tccgen.c:5529: by 0xa7c01929 gen_function() (included from ./libtcc.c, ./tcc.c)
    ./tccgen.c:5767: by 0xa7c02602 decl0() (included from ./libtcc.c, ./tcc.c)

that's because lib/bcheck.c runtime needs more fixes -- see next
patches.
2012-12-09 18:06:09 +04:00
Thomas Preud'homme
c4a18f47a2 Detect ARM CPU version in configure
Instead of guessing the ARM CPU version to compile for from tcc.h, we
now detect it in configure and output the value in config.h
2012-12-04 11:17:51 +01:00
Thomas Preud'homme
05b02a5581 arm-gen.c: Invalid operator test always false
Invalid operator test is always false in gen_opf for arm (found with
cppcheck). This patch fixes the issue.
2012-11-28 22:26:39 +01:00
Thomas Preud'homme
8d90205fd9 Fix OABI calling convention
OABI calling convention was broken since the addition of the hardfloat
calling convention in commit 7f6095bfec.
This commit fixes the breakage.
2012-11-28 22:26:39 +01:00
Kirill Smelkov
168aed4984 tests: btest should only run on targets supporting bcheck
After 40a54c43 (Repair bounds-checking runtime), and in particular
5d648485 (Now btest pass!) `make test` was broken on ARCH != i386,
because I've changed btest to unconditionally run on all arches.

But bounds-checking itsels is only supported on i386 and oops...

Fix it.

Reported-by: Thomas Preud'homme <robotux@celest.fr>
2012-11-24 12:54:03 +04:00
Kirill Smelkov
4744269494 Update .gitignore
The following files were not ignored (produced by build on i386 with
--enable-cross):

    arm-eabi-tcc
    arm-fpa-ld-tcc
    arm-fpa-tcc
    arm-vfp-tcc
    c67-tcc
    i386-win32-tcc
    lib/i386-win32/
    lib/x86_64-win32/
    x86_64-tcc
    x86_64-win32-tcc
2012-11-22 10:40:02 +04:00
Thomas Preud'homme
6eec931038 Only reference vfpr when available
A line in gfunc_call in arm-gen.c is referencing vfpr unconditionally.
Yet, this function is only available when TCC_ARM_VFP is set. While this
code is only triggered when TCC_ARM_VFP, it fails at compile time. This
commit fix the problem.
2012-11-21 12:21:51 +01:00
Thomas Preud'homme
15a315f4a5 Define TCC_ARM_EABI if using hardfloat ABI
TCC_ARM_EABI should be defined when compiling with hardfloat calling
convention. This commit rework the Makefile to distinguish between
calling convention and multiarch and define TCC_ARM_EABI when hardfloat
calling convention is used. The result is to first guess the calling
convention and then add the multiarch triplet if necessary.
2012-11-20 11:36:13 +01:00
Thomas Preud'homme
e2212738d4 Generate PLT thumb stub only when necessary
Generate PLT thumb stub for an ARM PLT entry only when at least one
Thumb instruction branches to that entry. This is a rewrite of the
previous patch.
2012-11-17 10:01:11 +01:00
Kirill Smelkov
ab24aaeca3 i386: We can change 'lea 0(%ebp),r' to 'mov %ebp,r'
Because that mov is 1 byte shorter, look:

    int *func()
    {
        return __builtin_frame_address(0);
    }

before patch:

00000000 <func>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   81 ec 00 00 00 00       sub    $0x0,%esp
   9:   8d 45 00                lea    0x0(%ebp),%eax   // <- here
   c:   e9 00 00 00 00          jmp    11 <func+0x11>
  11:   c9                      leave
  12:   c3                      ret

after patch:

00000000 <func>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   81 ec 00 00 00 00       sub    $0x0,%esp
   9:   89 e8                   mov    %ebp,%eax        // <- here
   b:   e9 00 00 00 00          jmp    10 <func+0x10>
  10:   c9                      leave
  11:   c3                      ret
2012-11-16 10:22:45 +04:00
Kirill Smelkov
b2a02961b4 Add support for __builtin_frame_address(level)
Continuing d6072d37 (Add __builtin_frame_address(0)) implement
__builtin_frame_address for levels greater than zero, in order for
tinycc to be able to compile its own lib/bcheck.c after
cffb7af9 (lib/bcheck: Prevent __bound_local_new / __bound_local_delete
from being miscompiled).

I'm new to the internals, and used the most simple way to do it.
Generated code is not very good for levels >= 2, compare

                gcc                         tcc

    level=0     mov    %ebp,%eax            lea    0x0(%ebp),%eax

    level=1     mov    0x0(%ebp),%eax       mov    0x0(%ebp),%eax

    level=2     mov    0x0(%ebp),%eax       mov    0x0(%ebp),%eax
                mov    (%eax),%eax          mov    %eax,-0x10(%ebp)
                                            mov    -0x10(%ebp),%eax
                                            mov    (%eax),%eax

    level=3     mov    0x0(%ebp),%eax       mov    0x0(%ebp),%eax
                mov    (%eax),%eax          mov    (%eax),%ecx
                mov    (%eax),%eax          mov    (%ecx),%eax

But this is still an improvement and for bcheck we need level=1 for
which the code is good.

For the tests I had to force gcc use -O0 to not inline the functions.
And -fno-omit-frame-pointer just in case.

If someone knows how to improve the generated code - help is
appreciated.

Thanks,
Kirill

Cc: Michael Matz <matz@suse.de>
Cc: Shinichiro Hamaji <shinichiro.hamaji@gmail.com>
2012-11-16 10:22:14 +04:00
Milutin Jovanović
e79c3533ec -Wno-unused-result now added only on gcc >= 4.4
This option does not exist in gcc 4.3 and earlier, and it breaks the build on
systems with older compilers. The makefile has been enhanced to test for the
version and adds it only if a newer compiler is detected.
2012-11-14 17:45:15 -05:00
Kirill Smelkov
40a54c4399 Repair bounds-checking runtime
On this weekend a thought came to me again that tinycc could be used for
scripting. Only its bounds-checking mode turned out to be broken, which
is a pity because bounds-checking is sometimes handy especially for
quickly written scripts.

Since tinycc is one of those small beautiful things, seldomly happening
in our times, I couldn't resist trying to fix it.

Thanks,
Kirill

* bcheck:
  Now btest pass!
  lib/bcheck: Prevent __bound_local_new / __bound_local_delete from being miscompiled
  lib/bcheck: Prevent libc_malloc/libc_free etc from being miscompiled
2012-11-14 10:50:34 +04:00
Kirill Smelkov
5d648485bd Now btest pass!
Thanks to two previous commits now btest tests pass, at least on Linux.

Signed-off-by: Kirill Smelkov <kirr@navytux.spb.ru>
2012-11-13 22:23:01 +04:00
Kirill Smelkov
cffb7af9f9 lib/bcheck: Prevent __bound_local_new / __bound_local_delete from being miscompiled
On i386 and gcc-4.7 I found that __bound_local_new was miscompiled -
look:

    #ifdef __i386__
    /* return the frame pointer of the caller */
    #define GET_CALLER_FP(fp)\
    {\
        unsigned long *fp1;\
        __asm__ __volatile__ ("movl %%ebp,%0" :"=g" (fp1));\
        fp = fp1[0];\
    }
    #endif

    /* called when entering a function to add all the local regions */
    void FASTCALL __bound_local_new(void *p1)
    {
        unsigned long addr, size, fp, *p = p1;
        GET_CALLER_FP(fp);
        for(;;) {
            addr = p[0];
            if (addr == 0)
                break;
            addr += fp;
            size = p[1];
            p += 2;
            __bound_new_region((void *)addr, size);
        }
    }

    __bound_local_new:
    .LFB40:
            .cfi_startproc
            pushl   %esi
            .cfi_def_cfa_offset 8
            .cfi_offset 6, -8
            pushl   %ebx
            .cfi_def_cfa_offset 12
            .cfi_offset 3, -12
            subl    $8, %esp            // NOTE prologue does not touch %ebp
            .cfi_def_cfa_offset 20
    #APP
    # 235 "lib/bcheck.c" 1
            movl %ebp,%edx              // %ebp -> fp1
    # 0 "" 2
    #NO_APP
            movl    (%edx), %esi        // fp1[0] -> fp
            movl    (%eax), %edx
            movl    %eax, %ebx
            testl   %edx, %edx
            je      .L167
            .p2align 2,,3
    .L173:
            movl    4(%ebx), %eax
            addl    $8, %ebx
            movl    %eax, 4(%esp)
            addl    %esi, %edx
            movl    %edx, (%esp)
            call    __bound_new_region
            movl    (%ebx), %edx
            testl   %edx, %edx
            jne     .L173
    .L167:
            addl    $8, %esp
            .cfi_def_cfa_offset 12
            popl    %ebx
            .cfi_restore 3
            .cfi_def_cfa_offset 8
            popl    %esi
            .cfi_restore 6
            .cfi_def_cfa_offset 4
            ret

here GET_CALLER_FP() assumed that its using function setups it's stack
frame, i.e. first save, then set %ebp to stack frame start, and then it
has to do perform two lookups: 1) to get current stack frame through
%ebp, and 2) get caller stack frame through (%ebp).

And here is the problem: gcc decided not to setup %ebp for
__bound_local_new and in such case GET_CALLER_FP actually becomes
GET_CALLER_CALLER_FP and oops, wrong regions are registered in bcheck
tables...

The solution is to stop using hand written assembly and rely on gcc's
__builtin_frame_address(1) to get callers frame stack(*). I think for the
builtin gcc should generate correct code, independent of whether it
decides or not to omit frame pointer in using function - it knows it.

(*) judging by gcc history, __builtin_frame_address was there almost
    from the beginning - at least it is present in 1992 as seen from the
    following commit:

    http://gcc.gnu.org/git/?p=gcc.git;a=commit;h=be07f7bdbac76d87d3006c89855491504d5d6202

    so we can rely on it being supported by all versions of gcc.

In my environment the assembly of __bound_local_new changes as follows:

    diff --git a/bcheck0.s b/bcheck1.s
    index 4c02a5f..ef68918 100644
    --- a/bcheck0.s
    +++ b/bcheck1.s
    @@ -1409,20 +1409,17 @@ __bound_init:
     __bound_local_new:
     .LFB40:
            .cfi_startproc
    -       pushl   %esi
    +       pushl   %ebp                // NOTE prologue saves %ebp ...
            .cfi_def_cfa_offset 8
    -       .cfi_offset 6, -8
    +       .cfi_offset 5, -8
    +       movl    %esp, %ebp          // ... and reset it to local stack frame
    +       .cfi_def_cfa_register 5
    +       pushl   %esi
            pushl   %ebx
    -       .cfi_def_cfa_offset 12
    -       .cfi_offset 3, -12
            subl    $8, %esp
    -       .cfi_def_cfa_offset 20
    -#APP
    -# 235 "lib/bcheck.c" 1
    -       movl %ebp,%edx
    -# 0 "" 2
    -#NO_APP
    -       movl    (%edx), %esi
    +       .cfi_offset 6, -12
    +       .cfi_offset 3, -16
    +       movl    0(%ebp), %esi       // stkframe -> stkframe.parent -> fp
            movl    (%eax), %edx
            movl    %eax, %ebx
            testl   %edx, %edx
    @@ -1440,13 +1437,13 @@ __bound_local_new:
            jne     .L173
     .L167:
            addl    $8, %esp
    -       .cfi_def_cfa_offset 12
            popl    %ebx
            .cfi_restore 3
    -       .cfi_def_cfa_offset 8
            popl    %esi
            .cfi_restore 6
    -       .cfi_def_cfa_offset 4
    +       popl    %ebp
    +       .cfi_restore 5
    +       .cfi_def_cfa 4, 4
            ret
            .cfi_endproc

i.e. now it compiles correctly.

Though I do not have x86_64 to test, my guess is that
__builtin_frame_address(1) should work there too. If not - please revert
only x86_64 part of the patch. Thanks.

Cc: Michael Matz <matz@suse.de>
2012-11-13 22:17:58 +04:00
Kirill Smelkov
646b51833f lib/bcheck: Prevent libc_malloc/libc_free etc from being miscompiled
On i386 and gcc-4.7 I found that libc_malloc was miscompiled - look:

static void *libc_malloc(size_t size)
{
    void *ptr;
    restore_malloc_hooks();     // __malloc_hook = saved_malloc_hook
    ptr = malloc(size);
    install_malloc_hooks();     // saved_malloc_hook = __malloc_hook, __malloc_hook = __bound_malloc
    return ptr;
}

	.type	libc_malloc, @function
libc_malloc:
.LFB56:
	.cfi_startproc
	pushl	%edx
	.cfi_def_cfa_offset 8
	movl	%eax, (%esp)
	call	malloc
	movl	$__bound_malloc, __malloc_hook
	movl	$__bound_free, __free_hook
	movl	$__bound_realloc, __realloc_hook
	movl	$__bound_memalign, __memalign_hook
	popl	%ecx
	.cfi_def_cfa_offset 4
	ret

Here gcc inlined both restore_malloc_hooks() and install_malloc_hooks()
and decided that

    saved_malloc_hook -> __malloc_hook -> saved_malloc_hook

stores are not needed and could be ommitted. Only it did not know
__molloc_hook affects malloc()...

So add compiler barrier to both install and restore hooks functions and
be done with it - the code is now ok:

    diff --git a/bcheck0.s b/bcheck1.s
    index 5f50293..4c02a5f 100644
    --- a/bcheck0.s
    +++ b/bcheck1.s
    @@ -42,8 +42,24 @@ libc_malloc:
            .cfi_startproc
            pushl   %edx
            .cfi_def_cfa_offset 8
    +       movl    saved_malloc_hook, %edx
    +       movl    %edx, __malloc_hook
    +       movl    saved_free_hook, %edx
    +       movl    %edx, __free_hook
    +       movl    saved_realloc_hook, %edx
    +       movl    %edx, __realloc_hook
    +       movl    saved_memalign_hook, %edx
    +       movl    %edx, __memalign_hook
            movl    %eax, (%esp)
            call    malloc
    +       movl    __malloc_hook, %edx
    +       movl    %edx, saved_malloc_hook
    +       movl    __free_hook, %edx
    +       movl    %edx, saved_free_hook
    +       movl    __realloc_hook, %edx
    +       movl    %edx, saved_realloc_hook
    +       movl    __memalign_hook, %edx
    +       movl    %edx, saved_memalign_hook
            movl    $__bound_malloc, __malloc_hook
            movl    $__bound_free, __free_hook
            movl    $__bound_realloc, __realloc_hook

For barrier I use

    __asm__ __volatile__ ("": : : "memory")

which is used as compiler barrier by Linux kernel, and mentioned in gcc
docs and in wikipedia [1].

Without this patch any program compiled with tcc -b crashes in startup
because of infinite recursion in libc_malloc.

[1] http://en.wikipedia.org/wiki/Memory_ordering#Compiler_memory_barrier
2012-11-13 22:17:51 +04:00
Thomas Preud'homme
1af3bca4ea Revert "Generate PLT thumb stub only when necessary"
Revert commit 891dfcdf3f since it assumes
*all* architectures supported by tcc have GOT offsets aligned on 2. A
rework of this commit is being done since without it all PLT entries
grow by 4 bytes.
2012-11-12 23:14:21 +01:00
Thomas Preud'homme
3c986eeae3 Add armv6l to ARM supported processors
Add armv6l to the list of supported ARM architecture (as returned by
uname -m) in ./configure
2012-11-11 20:01:01 +01:00
Thomas Preud'homme
14c99236da Call to veneers in ARM mode
Since commit c6630ef92a, Call to a veneer
when the final symbol to be reached is thumb is made through a blx
instruction. This is a mistake since veneers are ARM instructions and
should thus be called with a simple bl. This commit prevent the bl ->
blx conversion when a veneer is used.
2012-11-09 10:59:06 +01:00
Thomas Preud'homme
061b5799cc Allow source fortification
Source fortification now works correctly : it compiles without warning
except unused result and the resulting tcc is working fine. Hence let's
stop disabling source fortification and hide unused result instead.
2012-11-07 21:15:07 +01:00
Thomas Preud'homme
891dfcdf3f Generate PLT thumb stub only when necessary
Generate PLT thumb stub for an ARM PLT entry only when at least one
Thumb instruction branches to that entry.

Warning: To save space, this commit reuses the bit 0 of entries of
got_offsets array. The GOT offset is thus saved in a 31 bit value.
Make sure to divide by 2 (right shift by 1) an offset before storing it
there and conversely to multiply the value by 2 (left shift by 1) before
using it.
2012-11-07 20:51:33 +01:00
Thomas Preud'homme
e07802e39d Support R_ARM_THM_JUMP24 relocation to plt
Add thumb stubs switching from thumb mode to arm mode to *all* PLT
entries so that R_ARM_THM_JUMP24 relocations to PLT entries can be
satisfied.
2012-11-07 20:48:14 +01:00
Thomas Preud'homme
b0f08ace94 Create a clean target for tests2/Makefile
the absence of a clean target in tests2/Makefile make the clean target
in the main Makefile fails to complete. This commit create such a target
which removes the only file created when tests pass successfully.
2012-11-07 14:56:37 +01:00
Thomas Preud'homme
a7f010ee8a Honour *FLAGS everywhere
Add CPPFLAGS, CFLAGS and LDFLAGS everywhere it's missing.
2012-11-06 15:20:53 +01:00
Hitoshi Mitake
5eb64357b1 forbid invalid comparison of struct
Current tcc permits comparison of structs and comparison between
struct and other typed values.
2012-11-05 22:34:43 +09:00
Roy Tam
943574aba5 pe: fix tcc not linking to user32 and gdi32 2012-11-02 16:59:21 +08:00
Thomas Preud'homme
034dce4f04 Enable arm hardfloat calling convention
Use arm hardfloat calling convention when the system is using it
(detected by searching for hardfloat multiarch directory).
2012-10-28 19:55:23 +01:00
Thomas Preud'homme
fad68c9163 Add support for R_ARM_THM_{JUMP24,CALL} relocs
Add support for relocations R_ARM_THM_JUMP24 and R_ARM_THM_CALL. These
are encountered with gcc when compiling for armv6 or greater with
-mthumb flag and a call (conditional or not) is done.
2012-10-28 19:55:12 +01:00
Thomas Preud'homme
508df168f4 Fix commit 85f6fad3a6
Don't reset nocode_wanted with saved_nocode_wanted if it hasn't been
modified (and hence saved_nocode_wanted is uninitialized).
2012-10-25 20:14:55 +02:00
Thomas Preud'homme
cf95ac399c Error out in case of variable name clash
Error out when two local variable with same name are defined in the same
scope. This fixes bug #15597 in savannah's BTS.
2012-10-25 19:40:50 +02:00
Thomas Preud'homme
85f6fad3a6 Forbid VLA as static variables
Currently, VLA are not forbidden for static variable. This leads to
problems even if for fixed-size array when the size expression uses the
ternary operator (cond ? then-value : else-value) because it is parsed
as a general expression which leads to code generated in this case.

This commit solve the problem by forbidding VLA for static variables.
Although not required for the fix, avoiding code generation when the
expression is constant would be a nice addition though.
2012-10-25 18:07:13 +02:00
Thomas Preud'homme
9966fd4eae Only use blx if available
Introduce ARM version for the target architecture in order to determine
if blx instruction can be used or not. Availability of blx instruction
allows for more scenarii supported in R_ARM_CALL relocation. It should
also be useful when introducing support for the R_ARM_THM_CALL
relocation.
2012-10-16 00:31:56 +02:00
Thomas Preud'homme
c6630ef92a Fix R_ARM_CALL when target fonction is Thumb
With R_ARM_CALL, if target function is to be entered in Thumb mode, the
relocation is supposed to transform bl in blx. This is not the case
actually so this commit is there to fix it.
2012-10-10 00:21:26 +02:00
Thomas Preud'homme
2fe7fd9e87 Support for R_ARM_[THM_]MOV{W,T}_ABS[_NC} relocs
Add support for relocations R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS as well
as their Thumb2 counterpart R_ARM_THM_MOVW_ABS_NC and
R_ARM_THM_MOVT_ABS. These are encountered with gcc when compiling for
armv7-a and a data is loaded in a register, either in arm or Thumb2
mode. The first half of the data is loaded with movw ; the second half
is loaded with movt.
2012-10-10 00:19:43 +02:00
Sergey Vinokurov
3d409b0889 fix #include_next infinite loop bug, see http://savannah.nongnu.org/bugs/?31357 2012-09-20 22:12:05 +03:00
grischka
ca38792df1 tccrun: another incompatible change to the tcc_relocate API
We are now compatible with the 0.9,25 version though.  A special
value for the second (ptr) argument is used to get the simple
behavior as with the 0.9.24 version.
2012-09-01 11:33:34 +02:00
Thomas Preud'homme
56e23984b9 Disable callsave_test for arm
Disable callsave_test for arm since it uses alloca which is unavailable
on this platform.
2012-07-30 22:52:34 +08:00
Thomas Preud'homme
c9a2fbaad1 Add multiarch directory for arm hardfloat variant
Arm hardfloat variant uses a different ABI than arm and uses thus a
different multiarch directory for headers and libraries. This commit
detect whether the system uses the hardfloat variant and configure the
multiarch directory accordingly.
2012-07-29 23:46:45 +08:00
Thomas Preud'homme
d1694f7d7e get_reg(): try to free r2 for an SValue first
To be able to load a long long value correctly on i386, gv() rely on the
fact that when get_reg() look at an SValue it tries first to free the
register in r2 and then r. More information about the context can be
found at
http://lists.nongnu.org/archive/html/tinycc-devel/2012-06/msg00017.html
and later at
http://lists.nongnu.org/archive/html/tinycc-devel/2012-07/msg00021.html
2012-07-11 23:39:05 +02:00
Thomas Preud'homme
ed9c6b132a Fix R_ARM_REL32 relocation
Add missing break in the code handling R_ARM_REL32 relocation.
2012-07-09 18:41:55 +02:00
Vincent Lefevre
d27a0b3548 Incorrect shift result type on unsigned short first argument.
The code for shifts is now similar to code for binary arithmetic operations,
except that only the first argument is considered, as required by the ISO C
standard.
2012-07-06 14:22:37 +02:00
Vincent Lefevre
09b98a42a3 Tests on left-shift type. 2012-07-06 13:26:43 +02:00
Milutin Jovanović
d54e24cc0e tests: Minor adjustments selecting which tests are run on each platform.
The intent is for 'make test' to pass cleanly on each platform, and thus easier
spotting of regressions. Linux is best supported by most tests running and
passing. Mac OSX passes mosts tests that do not make/link with binary files,
due to lack of mach-o file support.

!!! I have very limited knowledge of Windows platform, and cannot comment why
all tests(1) fail. I have posted to newsgroup asking for someone to test
Windows platform.
2012-06-27 14:48:08 -04:00
Vincent Lefevre
240064c03b Incorrect shift result type with 64-bit ABI
On 2012-06-26 15:07:57 +0200, Vincent Lefevre wrote:
> ISO C99 TC3 says: [6.5.7#3] "The integer promotions are performed on
> each of the operands. The type of the result is that of the promoted
> left operand."

I've written a patch (attached). Now the shift problems no longer
occur with the testcase and with GNU MPFR's "make check".

--
Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
2012-06-27 08:23:52 -04:00
Milutin Jovanović
42c1b6ba38 tests: Added numerous tests.
The tests are taken almost verbatim from the open source project PicoC. It can
be found at https://code.google.com/p/picoc/.

The tests range from very simple/trivial ones to more complicated. My view is
that the more tests the better. Without tests like this I was very reluctant to
make any changes to tcc for the fear of breaking things.

The tests pass on Win32, OSX, Linux x86 and x86_64. One or two tests fail on
each platform due to differences in the runtime library.
2012-06-18 15:11:39 -04:00
Thomas Preud'homme
b0ebcfa7ba Detect multiarch on Kfreebsd and Hurd 2012-06-13 18:28:24 +02:00
Thomas Preud'homme
2e7a1af5d5 Evaluate configure arguments
Evaluate configure arguments to reproduce autotools behavior. Autotools
actually only expands a few variable and do it at make time but it makes
the change much simpler.
2012-06-12 20:48:01 +02:00
grischka
ad5f3758c3 Revert "Make ex1.c and ex4.c be executable on any systems"
Using /usr/bin/env tcc doesn't work as it was reported.  Revert to
using the full path which fails if the user installs tcc in non-default
location.  Then again this is just an example.

This reverts commit 27a428cd0f.
2012-06-12 15:45:13 +02:00
grischka
27d38bf23f tcc.c: fix argv index for parse_args
I probably broke that myself earlier.  In any case parse_args
needs to start with index 0 because it is is used also recursively
to expand the shebang command from scripts such as
    #!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
which arrives at tcc as only two argv's
    "tcc" "-run -L/usr/X11R6/lib -lX11"
2012-06-12 15:32:44 +02:00
Milutin Jovanović
32cd070c96 osx: Removed some optimizations for x86 builds as they were causing seg faults.
When using gcc compiler (as opposed to llvm) to build 32 bit tcc, compiler flags
-mpreferred-stack-boundary=2, -march=i386 and -falign-functions=2 were being
used. -march is redundant as -m32 is already being used. The other two seem to
be corrupting stack. I am not sure why this is the case, as the explanation of
the flags states that only running code size should be affected, but it does.

I think that is is safe to remove these flags altogether for all compilers and
platforms, especially since they are not being used for 64 bit builds. However
I do not want to apply such wide change without agreement from the people on the
mailing list.
2012-06-10 20:58:48 -04:00
Michael Matz
a42b029101 x86-64: Fix call saved register restore
Loads of VT_LLOCAL values (which effectively represent saved
addresses of lvalues) were done in VT_INT type, loosing the upper
32 bits.  Needs to be done in VT_PTR type.
2012-06-10 09:01:26 +02:00
Thomas Preud'homme
9a81dcab0a tccelf.c: Add R_ARM_REL32 relocation 2012-06-05 23:09:55 +02:00
Thomas Preud'homme
7f6095bfec Add support for arm hardfloat calling convention
See Procedure Call Standard for the ARM Architecture (AAPCS) for more
details.
2012-06-05 23:09:55 +02:00
Thomas Preud'homme
bfb00494eb Fix removal of vnrott
Make vrotb ST_FUNC so that arm-gen.c can use vrotb.
2012-06-05 23:09:55 +02:00
Thomas Preud'homme
731e07f175 Only warn for unknown options in configure script
This follows discussion started at
http://lists.nongnu.org/archive/html/tinycc-devel/2012-05/msg00015.html
2012-05-28 21:16:39 +02:00
Thomas Preud'homme
b56edc7b90 Several multiarch/biarch fixes
* Add multiarch directories for arm and i386
* Fix detection of biarch: /lib64/ld-linux-x86-64.so.2 is mandated by
  ABI and is thus always present, even if there is no biarch
* Define CONFIG_LDDIR directly with the right value in case of multiarch
  instead of defining it to /lib and then redifining it.
2012-05-23 00:14:15 +02:00
Thomas Preud'homme
a2c71af1ea Fix CONFIG_LDDIR usage
This patch fix 2 bugs in CONFIG_LDDIR usage:

* CONFIG_LDDIR used for 2 purposes

  there is confusion between the directory to find libraries, crt* files
  and headers and the directory in which the program interpreter is.
  These two directories are not related. The latter is specified by the
  ABI and should not be configurable while the former depends on the
  system (single arch, biarch, multiarch). This end a longstanding issue
  with amd64 program interpreter later propagated to other architecture
  interpreters.

* If multiarch is in effect, then the library directory should be /lib.
  /lib64 denotes biarch architecture, everything which is here would be
  in /lib/x86_64-linux-gnu instead.
2012-05-22 23:44:03 +02:00
Michael Matz
2daae0dc99 x86_64: Fix compares with NaNs.
Comparisons with unordered doubles was broken, NaNs always
compare unequal (and unordered) to everything, including
to itself.
2012-05-13 02:21:51 +02:00
Michael Matz
0394caf784 Emit spaces for -MD
TCCs make dependency generator is incompatible with the GNU
depcomp script which is widely used.  For TCC it has to go over
the output of -MD, (it detects it as ICC compatible), but the
sed commands it uses are confused by tabs in the output, so that
some rewrites aren't done.

Those tabs will then finally confuse make itself when the
generated .d files are included.  It reads them as goal commands
(leading tab), and is totally lost then.

Short of changing depcomp (hard because distributed with all kinds
of software), simply emit spaces for -MD.
2012-05-13 02:03:47 +02:00
Michael Matz
9ca9c82ff8 Fix comparing comparisons
Sometimes the result of a comparison is not directly used in a jump,
but in arithmetic or further comparisons.  If those further things
do a vswap() with the VT_CMP as current top, and then generate
instructions for the new top, this most probably destroys the flags
(e.g. if it's a bitfield load like in the example).

vswap() must do the same like vsetc() and not allow VT_CMP vtops
to be moved down.
2012-04-18 20:57:14 +02:00
Michael Matz
718fd591fa Make sizeof() be of type size_t
This matters when sizeof is directly used in arithmetic,
ala "uintptr_t t; t &= -sizeof(long)" (for alignment).  When sizeof
isn't size_t (as it's specified to be) this masking will truncate
the high bits of the uintptr_t object (if uintptr_t is larger than
uint).
2012-04-18 20:57:14 +02:00
Michael Matz
b068e29df7 x86_64: Implement GET_CALLER_FP
TCC always uses %rbp frames, so we can use that one.
2012-04-18 20:57:13 +02:00
Michael Matz
4c0d70ab07 Fix parsing function macro invocations
If a function macro name is separated from the parentheses in
an macro invocation the substitution doesn't take place.
Fix this by handling comments.
2012-04-18 20:57:13 +02:00
Michael Matz
15f4ac2b1a Fix detection of labels with a typedef name
This needs to be accepted:
  typedef int foo;
  void f (void) { foo: return; }
namespaces for labels and types are different.  The problem is that
the block parser always tries to find a decl first and that routine
doesn't peek enough to detect this case.  Needs some adjustments
to unget_tok() so that we can call it even when we already called
it once, but next() didn't come around restoring the buffer yet.
(It lazily does so not when the buffer becomes empty, but rather
when the next call detects that the buffer is empty, i.e. it requires
two next() calls until the unget buffer gets switched back).
2012-04-18 20:57:13 +02:00
Michael Matz
1d0a5c2515 x86_64: Fix segfault for global data
When offsetted addresses of global non-static data are computed
multiple times in the same statement the x86_64 backend uses
gen_gotpcrel with offset, which implements an add insn on the
register given.  load() uses the R member of the to-be-loaded
value, which doesn't yet have a reg assigned in all cases.

So use the register we're supposed to load the value into as
that register.
2012-04-18 20:57:13 +02:00
Michael Matz
86ac6b9bee x86_64: Fix indirection in struct paramaters
The first loop setting up struct arguments must not remove
elements from the vstack (via vtop--), as gen_reg needs them to
potentially evict some argument still held in registers to stack.

Swapping the arg in question to top (and back to its place) also
simplifies the vstore call itself, as not funny save/restore
or some "non-existing" stack elements need to be done.

Generally for a stack a vop-- operation conceptually clobbers
that element, so further references to it aren't allowed anymore.
2012-04-18 20:57:13 +02:00
Michael Matz
5c0a2366a3 Fix bitfield loads into char/short.
Removes a premature optimization of char/short loads
rewriting the source type.  It did so also for bitfield
loads, thereby removing all the shifts/maskings.
2012-04-18 20:57:13 +02:00
Michael Matz
6471ec0a2b Fix conversion in a?0:ptr.
(cond ? 0 : ptr)->member wasn't handled correctly.  If one arm
is a null pointer constant (which also can be a pointer) the result
type is that of the other arm.
2012-04-18 20:57:13 +02:00
grischka
f98c2306a0 libtcc: tcc_get_symbol uses the TCCState parameter
This allows using tcc_get_symbol on some other than the
current TCCState. (Suggested by David Mertens)
2012-04-18 18:48:26 +02:00
grischka
32a411914b support "x86_64-linux-gnu" subdirs with lib & include
suggested for newer ubuntu by Damian Gryski
2012-04-18 18:44:39 +02:00
grischka
f1b5c2ef4f tcc_realloc: auto "memory full" error 2012-04-18 18:43:55 +02:00
grischka
3c59f84240 tcc.h: unify multiple #ifdef CONFIG_TCC_BACKTRACE 2012-04-18 18:43:29 +02:00
grischka
ab936aeb8c cleanup some partially broken patches
- tests/Makefile:
  fix commit de54586d5b
  This hunk it unrelated to the other changes (which are about MacOSX).
  It is not useful and partially wrong.  Optional tests are meant to
  stay optional, btest would work only for i386

- tcc.h:
  fix commit c52d79605a by unknown
  The message says it's for MINTW but the patch has obviously
  no effect for MINGW (which defines __GNUC__).  However the patch
  seems useful for MSC which however needs _strto(u)i64 with underscore.

- Makefile:
  fix commit 5280293d6b
  Do not build tcc.o with -DONE_SOURCE because we finally build tcc
  from tcc.o and libtcc.a/so
2012-04-18 18:43:09 +02:00
grischka
5aaa067af4 win32: tcc.exe uses libtcc.dll 2012-04-18 18:38:11 +02:00
grischka
4274c44de7 tcc.c: fix previous commit "Use CString to concat linker options"
- remove redunant else branch
- zero-terminate linker_arg
- declare cstr_xxx as PUB_FUNC
  (which are functions used in tcc.c but not in the libtcc API.
   Useful for a tcc(.exe) that uses the libtcc.(so/dll))
- while at it, export PUB_FUNCs from dll
2012-04-18 18:32:37 +02:00
Gabriel Corneanu
214564b1dc Re-enable "Use CString to concat linker options"
This reverts commit 16202e054f.

Changed win32 build to use ONE_SOURCE just like libtcc.dll
Therefore CString can be used again...
2012-04-18 10:01:45 +02:00
Gabriel Corneanu
176876e5de add "nostdlib" option to libtcc 2012-04-18 09:48:57 +02:00
Thomas Preud'homme
16202e054f Revert "Use CString to concat linker options"
This reverts commit 1c11b857fe.

On windows, libtcc.c is compiled with ONE_SOURCE and then tcc.c is
linked to it. Thus tcc.c can only use public functions which cstr_* are
not.
2012-04-10 16:33:39 +02:00
Thomas Preud'homme
1c11b857fe Use CString to concat linker options
As suggested, change type of linker_arg variable to the more appropriate CString
type, since linker_arg is about dynamically grown string.
2012-03-20 16:01:12 +01:00
Thomas Preud'homme
2eee100c37 Fix use after free for linker_arg
elements in linker_arg are used in TCCState structure and must thus not
be freed when option parsing is finished. Declare linker_arg as a global
static variable and free it after tcc_delete has been called on TCCState
structure.

This fix commit 7fb0482a46
2012-03-16 19:23:54 +01:00
unknown
c52d79605a fix mingw compliation 2012-03-16 08:54:29 +08:00
Thomas Preud'homme
7fb0482a46 Support linker options passed in several -Wl param
ld support arguments to multiple-letter options being passed in two
ways:
* -opt=arg
* -opt arg

libtool generate command line of the second form. This commit add
support for the second form so that libtool works with tcc. The way it
is done is to concatenate all -Wl options into one and then pass it to
set_linker.
2012-03-15 00:25:40 +01:00
Thomas Preud'homme
1736a71b71 Consider long int constant as 64 bits on x86-64
Quick and dirty hack to consider long int constant (as in 1UL or 1L) as
64 bits integer on x86-64 non Windows systems.
2012-03-14 15:47:42 +01:00
Thomas Preud'homme
53c5715cca Remove vnrott (duplicate vrotb) 2012-03-14 15:39:16 +01:00
Thomas Preud'homme
3d25213c16 Inform user that -b only exists on i386. 2012-03-13 19:43:43 +01:00
Milutin Jovanovic
de54586d5b Further changes improving the OSX build. Everything builds. libtest passes.
Other tests still have issues, currently with weak linking.

One of the primary stumbling blocks on OSX is the lack of support for
mach-o binaries. Therefore all tcc usage on OSX has to be limited to elf
binaries, presumably produced by tcc itself.

Therefore I had to enable building of tiny_libmaker for OSX. Then changed
the make to use tcc and tiny_libmaker to compile the tcclib1.

In order to compile the tests, specifically the parts that use weak linking,
I have had to define MACOSX_DEPLOYMENT_TARGET to 10.2, which seems like a
hack, but extensive searching seems to indicate that this is the only way
to make apple gcc allow weak linking. Using any other value, bigger or smaller
breaks weak linking.

Also added _ANSI_SOURCE define required by some OSX headers, and some cosmetic
gitignore changes. I believe these changes should not impact other platforms.
2012-03-06 13:26:36 -05:00
grischka
ae191c3a61 x86_64: fix loading of LLOCAL floats
See also commit 9527c4949f

On x86_64 we need to extend the reg_classes array because load()
is called for (at least) R11 too, which was not part of reg_classes
previously.
2012-03-05 20:19:28 +01:00
grischka
a35b3059bb tcc.h: define TCC_IS_NATIVE
- disable tccrun feature for non-native (cross-) compilers
- define uplong for target adress size
- fix using -Wl,-Ttext=... for Win64 (tccpe: ADDR3264 imagebase)
2012-03-05 20:15:56 +01:00
Andrew Mulbrook
a0db7162af Fix assumption of 32bit long on portions of Elf
Modify tcc to accept convert full 64bits of specified text section
when converting on Win64. Write high bytes to the elf section address
as well. This allows creation of elf binaries located in offsets using
full 64 bit addresses.

Signed-off-by: Andrew Mulbrook <andrew262@gmail.com>
2012-03-03 11:10:15 -06:00
Andrew Mulbrook
5775911dad Revert "Multiple fixes for 64 bit sections"
This reverts commit d7a7c3769d.
2012-03-03 10:12:06 -06:00
Ramsay Jones
e343b1dfd4 Add __REDIRECT needed for Large File Support API on linux
Since commit 9b09fc3 ("Add support of asm label for functions",
05-09-2010) tcc has had the capability to rename functions at the
assembly level. This capability was subsequently used by commit
2596273 ("Add support for __REDIRECT_NTH needed with eglibc",
11-09-2010) to redirect long double functions on platforms which
did not support long double.

Here we add the companion macro __REDIRECT which is used (along
with __REDIRECT_NTH) in the glibc headers on Linux to support the
Large File API (when _FILE_OFFSET_BITS is set to 64).

Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
2012-02-29 16:38:24 +00:00
mob
d7a7c3769d Multiple fixes for 64 bit sections
This changeset attempts to fix a few problems when giving using
the high 32bits of a 64bit section offset. There are likely more
issues (or perhaps regressions) lurking in the muck here. In general,
this moves a few data type declarations to use uplong.  Also, add
support for 64bit mingw32 building under cygwin.  Because native
types are used for 64 bit offsets, this won't fix challenges with
cross compiling from 32bit -> 64bit.

Tested under cygwin, against binary compiled with
-Wl,-Ttext=0xffffff8000000000

Signed-off-by: Andrew Mulbrook <andrew262@gmail.com>
2012-02-26 19:02:51 -06:00
Milutin Jovanovic
6e13c35334 Attempt to fix 32 bit OSX build. The fix consists of adding -m32 and -m64
to the appropriate CFLAGS. In addition, memory hooks are very different
on OSX, so build of bcheck.c had to be disabled for now.

Change of the CFLAGS does affect builds on other platforms, and this needs
to be tested.
2012-02-16 11:24:14 -05:00
Milutin Jovanovic
8ca8b08890 Patch attempting to build OSX TinyCC.
Applied patch found on stackoverflow (link below). I also found some
related changes that looked like logically needed. The stackoverflow
changes addressed only two registers which were breaking a compile.
However reading the code in the same file shows two other register
accesses that, while not breaking the build, should have the same fix.

http://stackoverflow.com/questions/3712902/problems-compiling-tcc-on-os-x/3713144#3713144

The test driver was changed by changing 'cp -u' into 'cp' as '-u' is not
supported on mac osx.

I found that osx build required the WITHOUT_LIBTCC define. I suspect the
reason for this is tcc unability to handle mach-o files. In order to
properly address this I had to change 'configure' to propagate target os
name to Makefile.

Current state is that simple tests work, but not the whole 'make test'
suite runs.

To the best of my knowledge, these changes should not impact other
platforms.
2012-02-09 12:53:17 -05:00
Daniel Glöckner
9527c4949f i386: fix loading of LLOCAL floats
These loads clobbered ebx as TinyCC wanted to load the address into st0.
2012-01-23 01:45:11 +01:00
Thomas Preud'homme
3ab269c56a Error out when assigning void value.
tcc should now error out when compiling code like:

VOID ExitProcess(UINT uExitCode);
(…)
retCode = ExitProcess(pi.dwProcessId);
2012-01-22 21:18:38 +01:00
Thomas Preud'homme
9c25ed13b4 s/derefencing/dereferencing/ in i386-gen.c 2012-01-08 18:03:17 +01:00
Thomas Preud'homme
519a9040a1 Compile tccasm.c conditionally (TCC_CONFIG_ASM)
Only compile the content of tccasm.c if inline assembly is supported for
this architecture by testing the presence of macro TCC_CONFIG_ASM.
2012-01-06 18:34:21 +01:00
Thomas Preud'homme
83d57c06f4 Fix linkage of named file in loader script.
Remove the previous logic to link a named file with a loader script by
using tcc_add_dll instead. Hence, all files can be linked, not only
files ending in .so/.def.
2012-01-04 14:40:03 +01:00
Nicolas Limare
5f99fe2ff1 libtcc: add missing tcc_enable_debug() 2011-10-03 22:36:16 +02:00
Thomas Preud'homme
2dd3fb103e Don't define strtold and strtof on *BSD + uClibc
Don't define strtold and strtof on *BSD and uClibc as they are already
defined there since:

* 2001 (FreeBSD 4.4)
* 2009 (OpenBSD 4.5)
* 2009 (DragonFlyBSD)
* 2002 (uClibc)

See
http://lists.nongnu.org/archive/html/tinycc-devel/2011-07/msg00025.html
for a bit more details.
2011-08-12 18:43:37 +02:00
Daniel Glöckner
ab7ed48ee8 Fix problem with PLT and GOT relocs on armel.
TinyCC fails to link correctly to libraries when both R_ARM_PLT32 and
R_ARM_GOT32 relocation to a same symbol exist (see
http://lists.nongnu.org/archive/html/tinycc-devel/2010-05/msg00032.html
for more details).
The patch marks all undefined weak symbols found in external libraries
as strong. The value of all remaining weak symbols is set to zero just
before the section is output.

Note by Thomas Preud'homme: it's been 2 months in Debian without any new
bug report, hence commiting.
2011-08-12 18:28:45 +02:00
grischka
bf374a5f23 rename error/warning -> tcc_(error/warning) 2011-08-11 17:07:56 +02:00
grischka
74a24d77fd libtcc: minor adjustments
- use {B} to substitute tcc_lih_path (instead of \b)

- expand CONFIG_TCC_CRTPREFIX in CONFIG_TCC_LIBPATHS
  which fixes duplicate CONFIG_SYSROOT.

- put default CONFIG_SYSROOT ("") into tcc.h

- remove hack from commit db6fcce78f
  because $(tccdir)/include is already in sysincludes

- configure: error out for unrecognized options.

- win32/build-tcc.bat: put libtcc into base dir where it will
  find lib/include automatically, and build libtcc_test example.
2011-08-11 16:55:30 +02:00
Gabriel Corneanu
fd0cea8895 dll build + small adjustments 2011-08-10 12:42:14 +02:00
grischka
e844fb11c2 libtcc: support more than one crtprefix
Looks like gcc has that.  Oh Deer!
2011-08-06 16:49:30 +02:00
grischka
e6f3bf7f08 libtcc: cleanup the 'gen_makedeps' stuff 2011-08-06 16:11:58 +02:00
grischka
39a07cca58 tcc: fix -m32/64 & simplify
This cleans up the mess from commit
   8f98573658
and preceeding.

- make tcc -m64 work on windows
- execvp on windows returns 0 always, replace by spawnvp
- remove bizarre support for i386-win32-tcc -m64
2011-08-06 16:11:58 +02:00
grischka
5e5e29f8fd tcctest: switch weak_toolate proto with impl
gcc -O0 didn't like this.
2011-08-06 16:11:57 +02:00
grischka
f115c12346 x86-64: fix flags and zero-pad long doubles
This fixes a bug introduced in commit
    8d107d9ffd
that produced wrong code because of interference between
0x10 bits VT_CONST and x86_64-gen.c:TREG_MEM

Also fully zero-pad long doubles on x86-64 to avoid random
bytes in output files which disturb file comparison.
2011-08-06 16:11:56 +02:00
grischka
81cd0cf6fd configure: add switches to set search paths
--sysincludepaths=.. specify system include paths, colon separated"
     Sets CONFIG_TCC_SYSINCLUDEPATHS

   --libpaths=...       specify system library paths, colon separated"
     Sets CONFIG_TCC_LIBPATHS

   --crtprefix=...      specify location of crt?.o"
     Sets CONFIG_TCC_CRTPREFIX

   --elfinterp=...      specify elf interpreter"
     Sets CONFIG_TCC_ELFINTERP

Also the CONFIG_TCC_XXX were renamed to make them look
more consistent.

Also move the elf_interp definitions to tcc.h.
2011-08-06 16:11:12 +02:00
Thomas Preud'homme
9ffd77f18d Remove semicolon in x86-64 va_arg definition. 2011-08-05 20:32:57 +02:00
Thomas Preud'homme
0b6652003c Revert "Add a --multiarch-triplet switch to configure"
This reverts commit 76adc5770f.
2011-08-03 22:26:39 +02:00
Thomas Preud'homme
76adc5770f Add a --multiarch-triplet switch to configure
Add a --multiarch-triplet switch to configure. The switch will allow
files to be search for each default path in path/<triplet> and then
path.
Default paths handled that way:
- CONFIG_TCC_SYSINCLUDE_PATHS
- CONFIG_TCC_LIBPATH
- path to crt*.o
- path to libgcc_s.so.1

Path missing: elf interpreter path (will be handled in another commit)
2011-08-02 00:31:17 +02:00
Thomas Preud'homme
5e954fef32 Set CONFIG_TCC_CRT_PREFIX relative to CONFIG_SYSROOT
Set CONFIG_TCC_CRT_PREFIX relative to CONFIG_SYSROOT for consistency
with CONFIG_TCC_LDDIR.
2011-08-01 15:39:38 +02:00
grischka
df9cce24a8 Accept colon separated paths with -L and -I
This allows passing colon separated paths to
  tcc_add_library_path
  tcc_add_sysinclude_path
  tcc_add_include_path

Also there are new configure variables
  CONFIG_TCC_LIBPATH
  CONFIG_TCC_SYSINCLUDE_PATHS
which define the lib/sysinclude paths all in one and can
be overridden from configure/make

For TCC_TARGET_PE semicolons (;) are used as separators

Also, \b in the path string is replaced by s->tcc_lib_path
(CONFIG_TCCDIR rsp. -B option)
2011-08-01 01:10:36 +02:00
Thomas Preud'homme
626a907451 Revert "Force const. expr. in expr_cond outside function"
This reverts commit b2f5ee9b2d as it's
useless on mob.
2011-07-31 17:18:19 +02:00
Thomas Preud'homme
b2f5ee9b2d Force const. expr. in expr_cond outside function
Since no code should be generated outside a function, force expr_cond to
only consider constant expression when outside a function since the
generic code can generate some code.
2011-07-31 00:19:13 +02:00
Joe Soroka
339f961c11 fixed Makefile test targets 2011-07-22 02:12:49 -07:00
Joe Soroka
9b52e16a50 re-added negative-array-size testcase and fixed fix for it 2011-07-22 02:09:28 -07:00
grischka
d7d8458888 Revert "better constant handling for expr_cond"
It produced wrong code with one of my test projects.
This reverts commit cd3d1a45f3.
2011-07-16 15:53:30 +02:00
grischka
adc80009c8 elf.h: define SHF_MERGE etc. 2011-07-14 19:35:20 +02:00
grischka
8d107d9ffd win64: va_arg with structures 2011-07-14 19:24:53 +02:00
grischka
aa80e5b1ff tccpe: cleanup ELFW() macros etc. 2011-07-14 19:23:04 +02:00
grischka
d483ab322f tccrun: win32: improve exception handler 2011-07-14 19:11:12 +02:00
grischka
08083ddb21 tccrun: win32: improve rt_get_caller_pc 2011-07-14 19:11:11 +02:00
grischka
d59bd8be8e tccrun: rt_printline: fix no-stabs case 2011-07-14 19:11:10 +02:00
grischka
af83993810 tccrun: improve rt_printline output format
Prefix line with "file:linenumber:" such that editors
can easily jump to the source location
2011-07-14 19:11:08 +02:00
grischka
df4c0892f3 tccrun: win64: add unwind function table for dynamic code
This works only when tcc.exe is compiled using MSC.  MinGW does
something in the startup code that defeats it.
2011-07-14 19:09:49 +02:00
grischka
232650f8b3 tccgen: reset aligned attribute for next type
Basically, with:
    typedef __attribute__((aligned(16))) struct _xyz {
         ...
    } xyz, *pxyz;

we want the struct aligned but not the pointer.

FIXME: This patch is a hack, waiting for someone in the knowledge
of correct __attribute__ semantics.
2011-07-14 19:00:46 +02:00
grischka
5280293d6b make: create native tcc from separate objects
This was already possible using
    make NOTALLINONE=1
and is now the default.

To build as previously from one big source, use
    make ONE_SOURCE=1

Cross compilers are still build from one source because using
separate objects requires separate build directories one per
platform which currently is not (yet) supported by the makefile.

We could probably use gnu-makeish target variables like
    $(I386_CROSS): OUTDIR=build/i386
    $(X64_CROSS): OUTDIR=build/x86-64
and so on ...

Also NEED_FLOAT_TYPES for arm-gen is removed.  It was about
variables that are referenced from outside (libtcc, tccgen).
We could declare them in tcc.h (as with reg_classes) or have
them twice in arm-gen.c.  I chose option 2.
2011-07-14 18:45:37 +02:00
Thomas Preud'homme
4ccb5662cb Fix array_test: move params to local vars
array_test is declared and called with no parameters but defined with
one parameter. Compilation succeed (definition is after the use so the
compiler consider the declaration) as well as link (the function exist
and has the right name) but running the test segfault on i386 platforms.

This patch moves the parameter to local variable. If the intention was
to call it with an array parameter then feel free to fix it again.
2011-07-12 15:10:59 +02:00
grischka
45184e01d8 win32: add -Wl,--stack=xxx switch
For example:

    $ tcc -Wl,--stack=4194309

which means 4 MB.  Default is 1 MB.
2011-07-11 18:47:16 +02:00
grischka
7b573dc239 win32/include: enable _timezone etc variables.
which live in msvcrt.dll and need __declspec(import) which
works by now.

Also:
- _mingw.h: conditionally define WIN32_LEAN_AND_MEAN
- malloc.h: don't undef alloca
2011-07-11 18:44:47 +02:00
Joe Soroka
436c1a734f allow defining sysroot at compile-time 2011-07-11 00:20:48 -07:00
Joe Soroka
c71798c376 handle arrays with a flexible member but no initializer 2011-07-11 00:18:36 -07:00
Joe Soroka
cd3d1a45f3 better constant handling for expr_cond 2011-07-11 00:00:47 -07:00
Joe Soroka
38756b506f fix self-referential token pasting 2011-07-08 02:51:06 -07:00
Thomas Preud'homme
5cf5871aaf Use CONFIG_TCC_LDDIR for ld.so on all linux archs 2011-07-08 11:16:34 +02:00
Thomas Preud'homme
13121e220c Fix problem spotted in <4E15F966.4090102@gmx.de>
* Rename tcc_split_path_components
* Move tcc_split_path below memory wrapper section
* Ident tcc_split_path by 4
* Remove prefix and suffix clutter in tcc_split_path
* Don't dereference beyond the end of the search paths string
2011-07-08 10:51:26 +02:00
Joe Soroka
d01f65ef93 fix end-of-scope for self-referential macros 2011-07-08 00:55:34 -07:00
Thomas Preud'homme
f8656fbc3c Remove useless changes from 31ca000d in configure
After commit 4d6a4a26e0, the changes in
configure are no longer needed.
2011-07-07 15:32:20 +02:00
Thomas Preud'homme
27a428cd0f Make ex1.c and ex4.c be executable on any systems
Use /usr/bin/env to make ex1.c and ex4.c on any systems, wherever is
installed tcc.
2011-07-07 12:17:04 +02:00
Thomas Preud'homme
a03346c06e Document in README that ex4.c can be executed. 2011-07-07 12:15:43 +02:00
Thomas Preud'homme
571465d32b Revert "Make examples' shebang use target tcc bindir path"
This reverts commit cb2138f8b0.
2011-07-07 12:14:08 +02:00
Thomas Preud'homme
4d6a4a26e0 Add configuration of include subdirectories
Add the possibility to search headers in several subdirectories of
/usr/local/include and /usr/include. A possible use case would be for
tcc to search for headers in /usr/local/include/x86_64-linux-gnu,
/usr/local/include, /usr/include/x86_64-linux-gnu and /usr/include in
turn.
2011-07-07 12:10:57 +02:00
Thomas Preud'homme
a6775fc154 Introduce tcc_split_path_component for 31ca000d
Rewrite code introduced by 31ca000d and following commits around a new
function tcc_split_path_component.
2011-07-07 11:48:37 +02:00
Thomas Preud'homme
ca6ff4fada Free extra_libdir_str after use. 2011-07-06 10:26:46 +02:00
Thomas Preud'homme
38de06e334 Fix commit 31ca000d
* CONFIG_TCC_*LDDIR should not be exported if no --*lddir option is used.
* Don't write a : at the beginning of extralddir
2011-07-05 23:49:53 +02:00
Thomas Preud'homme
31ca000d72 Add multiarch dirs to linker search path
By default, tcc search libraries in /lib and /usr/local/lib while crt*.o
files are searched in /usr/lib and ld.so is searched in /lib.
Unfortunetely the path are hardcoded in source code. This patch allow
tcc to look in an other directory and also to look in extra directories.
It's then possible to make tcc search libraries in /lib/x86_64-linux-gnu
and /usr/local/lib/x86_64-linux-gnu while crt*.o files are searched in
/usr/lib/x86_64-linux-gnu and ld.so is searched in
/lib/x86_64-linux-gnu.
2011-07-05 11:16:12 +02:00
Thomas Preud'homme
cb2138f8b0 Make examples' shebang use target tcc bindir path
Use @BINDIR@ in shebang of examples to put the right path on the target
system. That is, use #!/usr/local/bin/tcc if tcc is installed in /usr/local/bin
and #!/usr/bin/tcc if tcc is installed in /usr/bin/tcc.
2011-06-18 00:45:20 +02:00
Thomas Preud'homme
3511e6e2a8 Default to create progs with symbols (incl. debug)
* Set CFLAGS entirely in configure if not already set.
* Compile bcheck.c with the same flags as the other source files
* Don't strip binaries by default (GB are cheap now) but provide a
  --strip-binaries option in configure script.
2011-06-17 22:22:04 +02:00
Thomas Preud'homme
330d2ee0fa Update Changelog
* Mention the various ARM improvement
* Make changelog consistent with regards to initial capital letters
* Fix credits for VLA
* Fix entry about asm label (variable are also supported)
2011-05-17 23:40:49 +02:00
Thomas Preud'homme
eb152022a0 make test work when LIBTCC1 not defined
Make libtest depends on LIBTCC1 instead of ../libtcc1.a and define
LIBTCC1 to $(TOP)/$(LIBTCC1) if LIBTCC1 is defined
2011-05-17 23:30:32 +02:00
grischka
c449ef2e1f tcc-doc: remove obsolete '-o option must also be given' 2011-05-17 21:55:05 +02:00
Daniel Glöckner
28a5b702f4 Fix calling ARM EABI functions returning big structures
The wrong type was tested to determine the size of the structure.
2011-05-17 02:24:45 +02:00
Thomas Preud'homme
8123e334e9 Support scratchbox, Nokia N900 and qemu arm archs
Add arm, armv5tejl and armv7l to the list of supported arm architectures
2011-05-16 15:30:52 +02:00
Thomas Preud'homme
66d992d883 Remove unused variables
Declare float type conditionally to not declare them conditionally when
they are not used.
2011-05-16 15:21:25 +02:00
Thomas Preud'homme
ee06ef9dd3 Remove unused variables
Remove unused local variables and declare them conditionally when they
are used only on some architectures.
2011-05-16 14:15:32 +02:00
Thomas Preud'homme
db9d5f0fa4 Improve weak aliases handling
* Include only the STB_GLOBAL alias symbol in .dynsym section
* Stop the loop when STB_GLOBAL symbol is found
* Reword / simplify comment
2011-05-16 13:49:08 +02:00
Thomas Preud'homme
921f002a6d make clean work when LIBTCC1 not defined
Don't call make -C lib clean if LIBTCC1 is not defined, else make clean
fails (for example of arm).
2011-05-14 16:21:45 +02:00
Joe Soroka
7391cf01a7 fix spurious vstack-leak warnings on error 2011-05-02 00:05:36 -07:00
Joe Soroka
48d81a796e libtcc.c: report vstack "leaks" only if compile succeeded 2011-04-14 01:02:42 -07:00
Joe Soroka
2b7a8eb8f5 use of TOK_alloca breaks cross compiler build
VLA inserts a call to alloca via enum TOK_alloca, but TOK_alloca
only exists on I386 and X86_64 targets.  This patch just emits an
error at compile-time if someone tries to compile some VLA code
for a TOK_alloca-less target. The best solution might be to just
push the problem to link-time, since the existence-or-not of a
alloca implementation can only be determined by linking.  It seems
like just declaring TOK_alloca unconditionally would achieve that,
but for now, this at least gets the cross compilers to build.
2011-04-12 00:17:08 -07:00
Joe Soroka
46e2dd7c32 tcctok.h: fix ifdef target/host confusion 2011-04-12 00:11:47 -07:00
Joe Soroka
812781cd11 simplify/rollback VLA pointer subtraction
I don't know if it makes a difference to gen_op(TOK_PDIV) or not,
but logically the ptr1_is_vla test in TP's VLA patch seems out of
order, where the patch to fix it would be:
------------------------------------------------------------------
@@ -1581,15 +1581,15 @@ ST_FUNC void gen_op(int op)
                 u = pointed_size(&vtop[-1].type);
             }
             gen_opic(op);
+            if (ptr1_is_vla)
+                vswap();
             /* set to integer type */
 #ifdef TCC_TARGET_X86_64
             vtop->type.t = VT_LLONG;
 #else
             vtop->type.t = VT_INT;
 #endif
-            if (ptr1_is_vla)
-                vswap();
-            else
+            if (!ptr1_is_vla)
                 vpushi(u);
             gen_op(TOK_PDIV);
         } else {
------------------------------------------------------------------

Instead of that patch, which increases the complexity of the code,
this one fixes the problem by just rolling back and retrying with
a simpler approach.
2011-04-11 23:39:27 -07:00
Joe Soroka
1b0f42f8ad update documentation to reflect VLA changes 2011-04-09 23:41:16 -07:00
Joe Soroka
1b8c094f39 remove no-longer-necessary naive fix for vla vstack leak 2011-04-09 23:04:01 -07:00
Joe Soroka
c85f77de70 prevent internal segfault on apparent VLA at file scope 2011-04-09 22:59:35 -07:00
Joe Soroka
1446b543ae VLA fix [3/3]: store VLA sizeofs in anonymous runtime stack vars 2011-04-09 22:52:25 -07:00
Joe Soroka
7c7ca3c6aa VLA fix [2/3]: removed VT_ARRAY from VT_VLA types
A VLA is not really an array, it's a pointer-to-an-array.
Making this explicit allows us to back out a few parts
of the original VLA patch and paves the way for the next
part of the fix, where a VLA will be stored on the runtime
stack as a pointer-to-an-array, rather than on the compile-
time stack as a Sym*.
2011-04-08 01:09:39 -07:00
Joe Soroka
cb2fa5eab9 VLA fix [1/3]: added testcase demonstrating VLA bug 2011-04-08 01:07:17 -07:00
Joe Soroka
174d61a56e move a comment to its correct location 2011-04-08 00:46:32 -07:00
Joe Soroka
b714af0405 add naive workaround for VLA vstack leak 2011-04-08 00:44:01 -07:00
Joe Soroka
6eb97c70b7 VLA leaks vstack. added warning to detect future leaks 2011-04-08 00:41:55 -07:00
Joe Soroka
c94f80502e VLA bcheck works via bound alloca; add test, remove warning 2011-04-06 15:27:45 -07:00
Joe Soroka
810aca9e68 clarify post_type() VT_STORAGE handling by moving it out 2011-04-06 12:08:50 -07:00
Joe Soroka
ace0f7f259 re-apply VLA by Thomas Preud'homme 2011-04-06 09:17:03 -07:00
Joe Soroka
17571298f3 handle c99 flexible array members less hackily 2011-03-18 17:50:42 -07:00
Joe Soroka
06a7c415a9 revert complicated & broken flexible array member handling 2011-03-18 17:47:35 -07:00
Joe Soroka
4062d787da sizeof(struct with "flexible array member") is wrong 2011-03-18 17:45:43 -07:00
Joe Soroka
0b8aa909a3 fix c99 for-loop init decl scope (thanks: grischka)
see http://lists.nongnu.org/archive/html/tinycc-devel/2011-03/msg00005.html
2011-03-08 15:19:54 -08:00
Joe Soroka
9ff91d4c6f clarify support for functions returning an array (try#2)
fixes first attempt:
http://repo.or.cz/w/tinycc.git/commitdiff/31fe1cc
2011-03-08 15:12:09 -08:00
Joe Soroka
91163f167e revert last commit. fails "make test"
test target in Makefile does not depend on tcc.
i'm not sure why, but i can think of at least one
good reason.  in my local tree I have it modified
to do so, but somehow inadvertently reverted that
so when i did "make test" before committing, it
didn't actually test my changes.  sorry.
2011-03-08 14:58:02 -08:00
Joe Soroka
31fe1cc62b clarify support for functions returning an array
previously, tcc would accept a prototype of a function returning
an array, but not giving those functions bodies nor calling them.
it seems that gcc has never supported them, so we should probably
just error out... but it's possible that someone already using
tcc includes some header that contains an unused prototype for
one, so let's continue to support that.
2011-03-08 14:13:08 -08:00
Joe Soroka
5eb82755db support c99 for-loop init decls (2nd attempt) 2011-03-08 13:36:04 -08:00
Joe Soroka
7fc2eee55c partially revert e23194a
see http://lists.nongnu.org/archive/html/tinycc-devel/2011-03/msg00002.html
2011-03-08 13:22:48 -08:00
Joe Soroka
b3a8eed49e revert last 3 commits. will find better way. 2011-03-08 12:56:13 -08:00
Joe Soroka
2d292e69a1 small change to previous whitespace-only commit 2011-03-08 09:26:36 -08:00
Joe Soroka
545a37b306 some indentation made prev patch pretty; removed it 2011-03-08 01:59:50 -08:00
Joe Soroka
89059f94c0 refactor post_type() to be explicit about its recursion 2011-03-08 01:47:31 -08:00
Joe Soroka
772b302187 added a note clarifying post_type() recursion
some ancient pre-K&R C allows a function to return an array
and the array brackets to be put after the arguments, such
that "int c()[]" means the same as "int[] c()"
see:
http://llvm.org/bugs/show_bug.cgi?id=2399
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#38703
2011-03-08 01:33:17 -08:00
Joe Soroka
585027aa96 tccelf: allow multiply defined weak symbols 2011-03-07 12:18:54 -08:00
Joe Soroka
e23194a1fa support c99 for-loop init decls 2011-03-07 11:28:31 -08:00
Joe Soroka
4fbe3cda33 use new weaken_symbol() to fix another real-world corner case 2011-03-07 01:05:09 -08:00
Joe Soroka
8bcb2ae1b2 factor out symbol weakening into new function 2011-03-07 01:02:23 -08:00
Joe Soroka
0f0c2d9c02 weak redefinition of a symbol should weaken the original 2011-03-07 00:25:27 -08:00
Joe Soroka
38cbb40e90 __typeof(t) should not include storage modifiers of t 2011-03-06 22:32:35 -08:00
grischka
5d55647a3c tccpp: fix problem in preprocess_skip with empty #
for example:

   #ifdef stuff
   # /* some comment */
   #endif
2011-03-06 19:13:12 +01:00
Changming Xu
c27e76aa2a unlink outfile first
file mode problem if the outfile already exists
2011-03-03 21:09:18 +08:00
Joe Soroka
c93eca4fe4 tccgen: handle __attribute((alias("target"))) 2011-03-03 01:58:45 -08:00
Joe Soroka
ce8c1886a5 collapse branch in decl(), making way for next patch 2011-03-03 01:07:36 -08:00
Joe Soroka
3beb383236 handle post-asm-label attributes on variables 2011-03-03 00:55:02 -08:00
Joe Soroka
823f832630 tcc: fix weak attribute handling 2011-03-02 13:31:09 -08:00
Changming Xu
684723488d Replace comment by a blank
- fix my prev commit:
	put declaration above statements to stay c89 compatible
- replace commit by a blank
        #define con(a, b) a/**/b
	this should yield a b, not ab
2011-03-01 09:19:43 +08:00
Changming Xu
185fba4189 tcc -E: append a ' ' after subst
We need a ' ' after subst of m in the following case

    #define m(name,r)  name ## r
    #define m0(a,b,c) int m(a,b)   c
    #define m1(a,b,c) int m(a,b)c
    m0(a, b, c);
    m1(a, b, c);
2011-02-27 10:15:15 +08:00
Joe Soroka
1b85b55059 i386-asm: support "pause" opcode 2011-02-24 09:38:13 -08:00
Joe Soroka
bec84fa00a tccasm: support alternate .type syntaxes 2011-02-24 09:24:02 -08:00
Joe Soroka
15b8a57096 tccpp: treat gas comments in .S files as raw text, not tokens 2011-02-23 15:13:08 -08:00
Jaroslav Kysela
85642f887c fix warning for tcctest.c introduced with my last commit 2011-02-22 13:55:21 +01:00
Jaroslav Kysela
ab73c9bc4e fix another static struct init issue (arrays with unknown size at end) 2011-02-22 12:15:45 +01:00
Jaroslav Kysela
dbefae52b0 Fix complex static initializers (handle additional '}' and '{' brackets)
- added an example to test suite
- the "warning: assignment discards qualifiers from pointer target type"
  is present but harmless
2011-02-22 12:15:44 +01:00
grischka
a3ebdd0aeb tccpe: support leading underscore for symbols
To make this the default, enable this line in libtcc.c:tcc_new:

    #if defined(TCC_TARGET_PE) && 0
        s->leading_underscore = 1;

and then recompile tcc and also libtcc1.a
2011-02-13 17:44:12 +01:00
Thomas Preud'homme
11b2d33523 Add support of asm label for variables.
Add support for asm labels for variables, that is the ability to rename
a variable at assembly level with __asm__ ("newname") appended in
its declaration.
See http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Asm-Labels.html for more
details.
2011-02-09 00:12:57 +01:00
Thomas Preud'homme
32a682b88f Fix fct asm label: only valid for declaration
- Fix function assembly label mechanism introduced in commit
  9b09fc376e to only accept alternative
  name for function declaration.
- merge the code with the one introduced in commit
  264a103610.
- Don't memorize token for asm label but directly the asm label.
2011-02-09 00:12:57 +01:00
Thomas Preud'homme
c23400278a Fix incorrect use of basic type as bitflags.
Fix incorrect use of basic types as bitflags and inefficiency in commit
cf36410e30
2011-02-07 23:46:20 +01:00
Thomas Preud'homme
cf36410e30 Complain for static fct declared w/o file scope
Error out on static function without file scope and give an explaination
to the user

This is a rewrite of e9406c09a3 but
considering problems raised about static local function pointers in
632ee5a540.
2011-02-06 22:50:05 +01:00
Joe Soroka
3b4b3b75a6 revert "update VT_STRUCT_SHIFT for new VT_VLA" 2011-02-04 17:54:08 -08:00
Thomas Preud'homme
db560e9439 Revert "Implement C99 Variable Length Arrays"
This reverts commit a5a50eaafe.
2011-02-05 02:33:46 +01:00
Thomas Preud'homme
38f6467c06 Revert "Reorder increasingly VT_* constants in tcc.h"
This reverts commit 7f00523e2e.
2011-02-05 02:33:46 +01:00
Thomas Preud'homme
c1b7267a2f Revert "Make TOK_alloca available for x86-64"
This reverts commit af26ac56bf.
2011-02-05 02:33:45 +01:00
Thomas Preud'homme
4b8470f3ae Revert "Disable C99 VLA when alloca is unavailable."
This reverts commit e3e5d4ad7a.
2011-02-05 02:33:45 +01:00
Joe Soroka
b0c50fbd4d update VT_STRUCT_SHIFT for new VT_VLA 2011-02-04 14:33:38 -08:00
grischka
2775173d4d fix crash with get_tok_str() in skip()
crash was triggered by numbers etc. as unexpected token, i.e.
everything that requires additional information with the token.
2011-02-04 20:23:43 +01:00
Thomas Preud'homme
e3e5d4ad7a Disable C99 VLA when alloca is unavailable.
* Disable C99 VLA detection when alloca is unavailable and protect the
  new reference to TOK_alloca in decl_initializer in order to compile
  and run for architecture without working alloca.

  Not all code of C99 VLA is commented as it would required many ifdef
  stanza. Just the detection is commented so that VT_VLA is never set
  any type and the C99 VLA code is compiled but never called. However
  vpush_global_sym(&func_old_type, TOK_alloca) in decl_initializer needs
  to be protected by an ifdef stanza as well because it uses TOK_alloca.

* include alloca and C99 VLA tests according to availability of
  TOK_alloca instead of relying on the current architecture
2011-02-04 15:24:48 +01:00
Thomas Preud'homme
af26ac56bf Make TOK_alloca available for x86-64
TOK_alloca is now available on x86-64 so make put definition of
TOK_alloca outside the BCHECK conditional macro definition but test if
arch is i386 or x86-64. This makes C99 VLA works (understand compile) on
x86-64.
2011-02-04 13:25:38 +01:00
Thomas Preud'homme
7f00523e2e Reorder increasingly VT_* constants in tcc.h 2011-02-04 02:22:25 +01:00
Thomas Preud'homme
a5a50eaafe Implement C99 Variable Length Arrays
Implement C99 Variable Length Arrays in tinycc:
- Support VLA with multiple level (nested vla)
- Update documentation with regards to VT_VLA
- Add a testsuite in tcctest.c
2011-02-04 02:22:25 +01:00
Thomas Preud'homme
d35a3ac375 Correct Changelog wrt. to fix attribution
Correctly attribute the patch bringing support for Debian GNU/kFreeBSD
kernels to Pierre Chifflier.
2011-02-04 02:22:15 +01:00
Joe Soroka
db6fcce78f tcc: add sysinclude path with -B, like gcc does 2011-02-02 00:00:12 -08:00
Joe Soroka
e939c4072c add -isystem cmdline option 2011-02-01 23:32:53 -08:00
Joe Soroka
b88677454b tcctest: plugged memleak (was polluting valgrind reports) 2011-02-01 16:05:57 -08:00
Joe Soroka
0d9376da70 tccasm: accept bracketed offset expressions 2011-02-01 15:53:48 -08:00
Joe Soroka
47b4cf22cd tccasm: accept "fmul/fadd st(0),st(n)" (dietlibc ipow/atanh) 2011-02-01 15:49:37 -08:00
Joe Soroka
87d84b7cb8 tccasm: allow one-line prefix+op things like "rep stosb" 2011-02-01 15:37:58 -08:00
Joe Soroka
a25325e9be tccasm: define __ASSEMBLER__ for .S files, like gcc does 2011-02-01 15:26:21 -08:00
Joe Soroka
75c6695932 tccpp: fix bug in handling of recursive macros 2011-02-01 13:23:40 -08:00
Joe Soroka
cf08675702 weak definitions overrule non-weak prototypes 2011-02-01 09:41:03 -08:00
Joe Soroka
c59d3426b8 tccasm: support .weak labels 2011-02-01 08:43:54 -08:00
Joe Soroka
4d5105c8f1 support weak attribute on variables 2011-02-01 00:37:53 -08:00
Joe Soroka
6839382480 asmtest: avoid testing against complex nop alignment in gas
.align #,0x90 in gas ignores the 0x90 and outputs any kind
of nop it feels like.  the one avoided by this patch is a 7
byte nop, which gas has been doing since at least 1999:
http://sourceware.org/ml/binutils/1999-10/msg00083.html

In order to match what gas does, we would need to make
code alignment target-specific, import a lot of code, and
face the question: exactly which gas {version,target,tune}
combo are we trying to match?  see i386_align_code in:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gas/config/tc-i386.c?annotate=1.460&cvsroot=src

The smart noppery is turned on via the special casing of 0x90
at line 438 in md_do_align in:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gas/config/tc-i386.h?annotate=1.1&cvsroot=src
2011-01-23 16:46:24 -08:00
Joe Soroka
2047f88334 i386-asm: accept retl as a synonym for ret 2011-01-21 01:35:28 -08:00
Joe Soroka
f43fafc680 accept multiple comma separated symbols for .globl/.global directives, like gas does 2011-01-20 02:00:50 -08:00
Sergei Trofimovich
0a50e6c933 tcc.c: fix an error when you build an object file with '-pthread' key set
The problem was partially fixed by Henry in the following patch:

    tcc.c: skip -lpthread when -c option specified

But that patch had one brawback: it is sensitive to argument order,
as decision is taken during commandline parsing:

    $ tcc -c a.c -o a.o -pthread # 1. works fine
    tcc: error: file 'a.c' not found

    $ tcc -pthread -c a.c -o a.o # 2. blows
    tcc: error: cannot specify libraries with -c

This patch fixes case 2.

Signed-off-by: Sergei Trofimovich <st@anti-virus.by>
2011-01-04 11:17:52 +02:00
Sergei Trofimovich
d97a25fbdd lib/alloca*: mark ELF stack access flags as nonexecutable
Signed-off-by: Sergei Trofimovich <st@anti-virus.by>
2011-01-04 10:38:52 +02:00
Sergei Trofimovich
288831854b Makefile: respect LDFLAGS (set via --extra-ldflags=)
Signed-off-by: Sergei Trofimovich <st@anti-virus.by>
2011-01-04 10:22:02 +02:00
Shinichiro Hamaji
0ed7ba3f5e Support struct arguments with stdarg.h
- add __builtin_va_arg_types to check how arguments were passed
- move most code of stdarg into libtcc1.c
- remove __builtin_malloc and __builtin_free
- add a test case based on the bug report
  (http://www.mail-archive.com/tinycc-devel@nongnu.org/msg03036.html)
2010-12-28 19:32:40 +09:00
Shinichiro Hamaji
07fd82b411 Make alignments for struct arguments 8 bytes
The ABI (http://www.x86-64.org/documentation/abi.pdf) says
"The size of each argument gets rounded up to eightbytes"
2010-12-28 19:09:59 +09:00
Shinichiro Hamaji
83f0a7b6f8 Test va_copy in tcctest.c 2010-12-28 17:53:56 +09:00
Shinichiro Hamaji
45e1ae2896 One more fix for tcc -run
We don't need r_addend for addresses in PLT.
2010-12-28 17:44:51 +09:00
Shinichiro Hamaji
d457addfc3 Fix for the previous commit.
R_X86_64_PLT32 for .so doesn't need DLL relocation.
2010-12-28 16:52:21 +09:00
Shinichiro Hamaji
0ae39f1957 Handle r_addend and R_X86_64_PLT32 properly.
- r_addend should be applied for PLT entries as well
- R_X86_64_PLT32 should be handled just like R_X86_64_PC32
- spec says GLOB_DAT and JUMP_SLOT don't need r_addend (not tested)
  http://www.x86-64.org/documentation/abi.pdf

Now we can -run ELF objects generated by GCC.
2010-12-28 16:14:30 +09:00
Henry Kroll III
48e325df3c configure: --sharedir defaults to /usr/local/share 2010-12-23 06:36:07 -08:00
Henry Kroll III
f449f98dec configure: --sharedir documentation root 2010-12-22 04:42:39 -08:00
Henry Kroll III
44f7055a04 make: fix cannot find -ltcc with --disable-rpath 2010-12-21 09:47:17 -08:00
Henry Kroll III
73cb4392ab make: fix install with CC=tcc and potential link problem 2010-12-20 06:20:08 -08:00
Henry Kroll III
90355c78ed configure: add --disable-rpath option (Fedora) 2010-12-20 05:55:54 -08:00
Henry Kroll III
3b3a7cc8ba configure: improvements to option --tccdir 2010-12-20 05:38:59 -08:00
Henry Kroll III
d16722481f tcc: add unsupported option -pedantic 2010-12-20 04:23:30 -08:00
Henry Kroll III
8f98573658 tcc: -m32 prefix "win32-" when file extension is present 2010-12-13 00:00:18 -08:00
Henry Kroll III
c6f5d819af tcc: fix format string in error handler 2010-12-08 01:05:50 -08:00
Henry Kroll III
ffb9fcc5a2 tcc: oops, error handler does not accept format strings 2010-12-08 00:52:33 -08:00
Henry Kroll III
b3be007afa tcc: fix -m32 and add -m64 option 2010-12-08 00:27:06 -08:00
Henry Kroll III
f3d3ab5a69 tcc: move undef out of if block 2010-12-06 16:36:00 -08:00
Henry Kroll III
10a08a372f Merge branch 'mob' of git://repo.or.cz/tinycc into kroll 2010-12-06 16:25:33 -08:00
Henry Kroll III
bb7bb37fe2 tcc: add -m32 option to x86_64 cross compilers 2010-12-06 16:17:20 -08:00
Shinichiro Hamaji
f2d7998a96 Copy tcclib.h to tests directory so GCC uses its own headers.
86ffc48129

removed this cp command. However, it was necessary to pass tests on x86-64
because include/stdarg.h is different from GCC's definition on x86-64.
2010-12-07 03:04:45 +09:00
Henry Kroll III
33f86ada92 trim unnecessary bits from my previous 3 commits 2010-12-05 12:47:50 -08:00
Henry Kroll III
1c821373ad make: i386/libtcc1.a for i386-tcc (x86_64 to i386 cross) 2010-12-05 01:04:28 -08:00
Henry Kroll III
50ff5ed790 make: cross compilers exist before using them (fixes parallel make) 2010-12-04 20:15:37 -08:00
Henry Kroll III
eb550ed23b tcc: add option -s for gcc compatibility (ignored) 2010-12-04 16:04:33 -08:00
grischka
69fe7585a2 tiny_libmaker: strip leading directory to avoid buffer overrun
The arhdr.ar_name has 16 bytes.  Long object names esp. with
leading directory were causing a buffer overrun which was
detected by glibc.
2010-12-04 16:56:58 +01:00
grischka
21c2a68aa0 tccelf/tcccoff: fix some type conversion warnings 2010-12-04 16:48:15 +01:00
grischka
86ffc48129 make: new lib/Makefile for libtcc1.a on more platforms
win32/64 cross-compilers now build libtcc1.a and install it
together with the windows headers in a 'win32' sub-directory
of TCCDIR.
2010-12-04 16:47:08 +01:00
Henry Kroll III
2ce9a0e2fe needs lib path on bcheck.o fixes undefined symbol '__try__' 2010-12-02 21:43:46 -08:00
Henry Kroll III
3b8b290a45 make cross compilers an expert option in configure --help 2010-12-02 20:33:11 -08:00
Henry Kroll III
94e72b16e7 Add --enable-cygwin option to build on windows with cygwin+mingw32 2010-12-02 20:16:32 -08:00
Henry Kroll III
c5d3ce684a Changelog: document some of the recent changes 2010-12-02 14:41:26 -08:00
Henry Kroll III
2215567d7a Makefile: fix clean target, bcheck, add comments 2010-12-02 14:39:34 -08:00
Henry Kroll III
a2779556b4 split cross libtcc1.a to separate directories 2010-12-02 03:08:57 -08:00
Henry Kroll III
03b23994f1 tccpe.c: fallback to libtcc1.a for other targets (ARM) 2010-11-30 18:52:43 -08:00
Henry Kroll III
165d136614 Makefile: cleanup leftovers on cross build. really works now 2010-11-30 16:17:37 -08:00
Henry Kroll III
93ef24e6fe Makefile: fix typo and resulting workaround 2010-11-30 16:08:33 -08:00
Henry Kroll III
b7d89ff822 Makefile: fix Linux cross install, cleanup 2010-11-30 15:35:32 -08:00
Henry Kroll III
c1a437add7 tccpe.c: Makefile: --enable-cross win64 cross library build 2010-11-30 15:15:55 -08:00
Henry Kroll III
9e406656c7 tcc.c: skip -lpthread when -c option specified 2010-11-30 13:58:18 -08:00
Henry Kroll III
0d38e3b663 make CC=tcc install: fixes strip:tcc: File format not recognized 2010-11-30 13:34:09 -08:00
Henry Kroll III
8185070841 Makefile: Add .PHONY targets 2010-11-30 13:09:16 -08:00
Henry Kroll III
52b75c5fa0 Makefile: Put i386-win32-tcc back into --enable-cross install 2010-11-30 02:42:38 -08:00
Henry Kroll III
7b18df138d Makefile: build --config-cross libtcc1.a directly to win32/lib 2010-11-30 01:49:34 -08:00
Henry Kroll III
48a2a8dabd Remove unnecessary $(PROGS_CROSS) from non-cross builds. 2010-11-29 21:09:20 -08:00
Henry Kroll III
ddea94daea Makefile: TCC=tcc 2010-11-28 16:11:40 -08:00
Henry Kroll III
9a986f374e configure: allow changing installation directory 2010-11-28 15:54:27 -08:00
Henry Kroll III
3d35b6b36d Makefile: --enable-cross on x86_64 simplified 2010-11-28 15:51:03 -08:00
grischka
f332bb3bca tccpe: typedef unsigned int DWORD for cross compilers.
This fixes the i386-win32-tcc cross-compiler on x86-64 linux
platform.

I verified that it produces identical binaries for 'hello_win.exe'
and 'tcc.exe' (tcc compiled by itself) compared to the output of
the native tcc on windows.
2010-11-27 15:02:57 +01:00
grischka
9bd69bf49f build: remove #include "config.h" from target dependent files
This is to make cross build of libtcc1.a easier.
2010-11-26 20:46:54 +01:00
grischka
c4eef48025 libtcc: fix s->include_stack_ptr used uninitialized in tcc_open 2010-11-26 20:46:50 +01:00
Henry Kroll III
77e4679aec x86_64: finish biarch path fixup 2010-11-25 10:08:58 -08:00
grischka
44e84bb22a tccpp: fix token pasting ##
This patch takes advantage of new function tcc_open_bf
from previous commit.
2010-11-25 13:30:31 +01:00
grischka
e97bf88bad libtcc: new function tcc_open_bf to create BufferedFile
Use it in:
- tcc_open
- tcc_compile_string
- tcc_define_symbol
- tcc_assemble_inline
2010-11-25 13:29:15 +01:00
Henry Kroll III
f1c9f649da x86_64: fix --with-libgcc and simplify biarch paths 2010-11-25 02:57:19 -08:00
Henry Kroll III
9036c18170 tcc: Linux -pthread option sets -D_REENTRANT and -lpthread 2010-11-24 16:42:08 -08:00
Henry Kroll III
f0afec709e Makefile: x86_64 win32-cross add clean: target 2010-11-06 02:39:28 -07:00
Henry K
e250ffb319 Makefile: edit comments 2010-10-29 00:40:16 -07:00
Henry Kroll III
24d6a93f44 Makefile: cross-copiler tcc1.def is now libtcc1.a, ignore mv errors 2010-10-29 00:40:06 -07:00
Henry Kroll III
c635976cd7 Force gcc for x86_64 --enable-cross 2010-10-28 22:08:44 -07:00
Henry Kroll III
fb498eb925 selinux: correct ftruncate, fix bus error in tcc -run 2010-10-27 03:54:12 -07:00
Ben Bacarisse
14673d0c49 Fix binding of assignment expressions. 2010-10-25 15:40:30 +01:00
grischka
9228842fa7 win32: register SEH in startup code (i386 only)
Needed to handle signal() etc. with msvcrt
2010-10-19 13:15:06 +02:00
Thomas Preud'homme
036d94112d Remove ifdef STT_GNU_IFUNC test in tccrun.c
STT_GNU_IFUNC is always defined (there is no conditional definition of
it) so the ifdef test for STT_GNU_IFUNC in tccrun.c has no reason to
be.
2010-10-10 16:25:41 +02:00
Thomas Preud'homme
c1c4040d75 Explicit license in tiny_libmaker.c
Explicit the license in tiny_libmaker.c to LGPLv2. Confirmation of the
license of this file can be found at
http://lists.nongnu.org/archive/html/tinycc-devel/2010-07/msg00004.html
2010-10-07 10:43:22 +02:00
Sergei Trofimovich
872cc430c0 info doc: fix --infodir to respect DESTDIR for 'make install'
info files are introduced by commit 3f829d11ff

This patch helps packagers to avoid problems when install to $DESTDIR

    >>> Starting src_install
    make -j3 bindir=/tmp/paludis/dev-lang-tcc-9999/image//usr/bin libdir=/tmp/paludis/dev-lang-tcc-9999/image//usr/lib tccdir=/tmp/paludis/dev-lang-tcc-9999/image//usr/lib/tcc includedir=/tmp/paludis/dev-lang-tcc-9999/image//usr/include docdir=/tmp/paludis/dev-lang-tcc-9999/image//usr/share/doc/tcc-9999 mandir=/tmp/paludis/dev-lang-tcc-9999/image//usr/share/man install
    mkdir -p "/tmp/paludis/dev-lang-tcc-9999/image//usr/bin"
    install -m755 tcc "/tmp/paludis/dev-lang-tcc-9999/image//usr/bin"
    mkdir -p "/tmp/paludis/dev-lang-tcc-9999/image//usr/share/man/man1"
    install tcc.1 "/tmp/paludis/dev-lang-tcc-9999/image//usr/share/man/man1"
    mkdir -p /usr/share/info
    install  tcc-doc.info "/usr/share/info"
    ACCESS DENIED  open_wr:      /usr/share/info/tcc-doc.info
    install: cannot create regular file `/usr/share/info/tcc-doc.info': Permission denied
    make: *** [install] Error 1
    /usr/libexec/paludis/utils/emake: emake returned error 2

Signed-off-by: Sergei Trofimovich <st@anti-virus.by>
2010-09-21 10:04:05 +03:00
Thomas Preud'homme
b8adf0090e Move asm label functions from tccasm.c to tccgen.c
* Move functions parse_asm_str and asm_label_instr from tccasm.c to
  tccgen.c
* Remove CONFIG_TCC_ASM_LABEL macro as asm label are available on all
  archs.
See:
http://lists.nongnu.org/archive/html/tinycc-devel/2010-09/msg00026.html
for the rationale.
2010-09-14 23:21:15 +02:00
Thomas Preud'homme
2596273fce Add support for __REDIRECT_NTH needed with eglibc.
Add support for __REDIRECT_NTH as eglibc makes use of this macro to
redirect long double functions to long functions on arch not supporting
long double.
2010-09-12 01:19:19 +02:00
Thomas Preud'homme
3f829d11ff Add info file creation into tcc build process
Add info file creation in tcc Makefile
2010-09-10 21:19:01 +02:00
Thomas Preud'homme
36f74e46b4 Add missing dircategory and direntry to texi file 2010-09-10 21:11:45 +02:00
Thomas Preud'homme
776364f395 Add support for __FreeBSD_kernel__ kernel
Add support for kfreebsd-i386 and kfreebsd-amd64 Debian arch with
thanks to Pierre Chifflier <chifflier@cpe.fr>.
2010-09-10 21:09:07 +02:00
Thomas Preud'homme
2887f40f76 Add support for GNU/Hurd
+ Add i686-AT386 to the list of x86 platform
+ Define SA_SIGINFO is not defined
2010-09-10 20:55:54 +02:00
Thomas Preud'homme
9b09fc376e Add support of asm label for functions.
Add support for asm labels for functions, that is the ability to rename
a function at assembly level with __asm__ ("newname") appended in
function declaration.
2010-09-10 20:15:03 +02:00
grischka
a7fb00e887 tccmain: simplify option help 2010-09-08 19:13:36 +02:00
Shinichiro Hamaji
c31dc7aa0c Fix casts from 32bit integer types to 64bit integer types.
This bug was reported in
http://lists.gnu.org/archive/html/tinycc-devel/2010-08/msg00050.html

In this case, we should not emit any code when we cast from VT_FUNC to VT_PTR.
2010-08-31 08:35:31 +09:00
Shinichiro Hamaji
9d347f8742 Probably wrong stack alignment for struct on Win64 2010-08-27 02:49:09 +09:00
Shinichiro Hamaji
1f6781f0ee Fix alignment around struct for SSE.
- Fix a wrong calculation for size of struct
- Handle cases where struct size isn't multple of 8
- Recover vstack after memcpy for pushing struct
- Add a float parameter for struct_assign_test1 to check SSE alignment
2010-08-27 02:32:19 +09:00
grischka
4ab4efd3a6 Revert "implemented C99 for loop with variable declaration"
This reverts commit 433ecdfc9d.

The patch breaks e.g. with
    for ((i = 10); --i;);

In particular to check for a type decl. this is not sufficient:
    if (tok < TOK_UIDENT) {

A future approach to c99 loop variables might instead use:
    if (parse_btype(...)) {

plus refactor function decl() accordingly.
2010-08-21 13:39:12 +02:00
Kirill Smelkov
7901d1e3ad tcc_set_linker: mimic all option forms as supported by GNU ld
Namely

 *  `-option' or `--option'  (start with double or single dash)
 *  `-param=val' or `-param,val'

See GNU ld manual (2.1 Command Line Options)
2010-08-12 23:30:21 +04:00
Thomas Preud'homme
bcc9137a10 Add support for indirect functions as externals.
Add link support to use indirect functions defined in external modules
2010-08-09 20:20:09 +02:00
grischka
82c5edb31c Avoid crash with "Avoid a crash with weak symbols for "make test""
This fixes commit 197a6acb30
which fixed commit 95b9a477b6

Also remove useless example files
2010-06-30 20:25:04 +02:00
Thomas Preud'homme
5e6fabefd7 Revert "Use mktemp to generate temp files."
Doesn't seem to work on windows
This reverts commit 27988c5e66.
2010-06-23 14:10:22 +02:00
Thomas Preud'homme
27988c5e66 Use mktemp to generate temp files.
Fix the $RANDOM bashism properly by using mktemp.
mktemp is part of MSYS so this should work on UNIXes and Windows
2010-06-22 18:40:35 +02:00
Kirill Smelkov
9775aea1ab Merge branch 'kirr/tcc-MD' into mob
Hello up there.

I'm trying to change gcc to tcc for faster develpment on slow machines,
and the first obstacle that turned out was lack of dependency generation
on tcc side.

Attached patches try to fix that.

Thanks,
Kirill

* tcc-MD:
  .gitignore += tags
  tcc: Explicitly require -l<lib> for libraries
  Document what tcc_fileextension does
  tcc -E: Let output_default be <file>.o instead of a.out
  tcc: Draft suppoprt for -MD/-MF options
  tcc: Refactor "compute default outfile name" into libtcc function
  Add input files/libs and reloc_output switch to TCCState
  tcc: Fix typo in error (it's '%s', not '%s)
  chmod a-x i386-gen.c
  .gitignore += *.o *.a
  .cvsignore -> .gitignore
2010-06-21 20:50:41 +04:00
Kirill Smelkov
2fe5210a33 .gitignore += tags 2010-06-21 20:49:46 +04:00
Kirill Smelkov
93de8d8038 tcc: Explicitly require -l<lib> for libraries
Previously it was possible to specify e.g. -q<lib> and still link with
lib. Avoid such behaviour by checking for '-l' instead of '-l.'
2010-06-21 20:49:46 +04:00
Kirill Smelkov
441a089aa4 Document what tcc_fileextension does
This is evident, but won't hurt
2010-06-21 20:49:46 +04:00
Kirill Smelkov
1203348302 tcc -E: Let output_default be <file>.o instead of a.out
This affectes where `tcc -E -MD file.c` will place generated dependency
information -- previously, for `tcc -E` output_default was a.out, and so
deps were put into a.d .

Avoid this behaviour, by treating `tcc -E` as `tcc -c` with respect to
output_default computation.

This will not hurt anything else (preprocessor outputs to either stdout,
or to explicitely given (-o <file>) destination, so no default filename
is used here), and on the other hand `tcc -E -MD file.c` now puts
dependencies into file.d (the same behaviour as for gcc -E).

v2:

- restructured condition a bit to make it more clear
2010-06-21 20:49:46 +04:00
Kirill Smelkov
0c928da96d tcc: Draft suppoprt for -MD/-MF options
In build systems, this is used to automatically collect target
dependencies, e.g.

    ---- 8< (hello.c) ----
    #include "hello.h"
    #include <stdio.h>

    int main()
    {
        printf("Hello World!\n");
        return 0;
    }

$ tcc -MD -c hello.c    # -> hello.o, hello.d
$ cat hello.d
hello.o : \
        hello.c \
        hello.h \
        /usr/include/stdio.h \
        /usr/include/features.h \
        /usr/include/bits/predefs.h \
        /usr/include/sys/cdefs.h \
        /usr/include/bits/wordsize.h \
        /usr/include/gnu/stubs.h \
        /usr/include/bits/wordsize.h \
        /usr/include/gnu/stubs-32.h \
        /home/kirr/local/tcc/lib/tcc/include/stddef.h \
        /usr/include/bits/types.h \
        /usr/include/bits/wordsize.h \
        /usr/include/bits/typesizes.h \
        /usr/include/libio.h \
        /usr/include/_G_config.h \
        /usr/include/wchar.h \
        /home/kirr/local/tcc/lib/tcc/include/stdarg.h \
        /usr/include/bits/stdio_lim.h \
        /usr/include/bits/sys_errlist.h \

NOTE: gcc supports -MD only for .c -> .o, but in tcc, we generate
dependencies for whatever action is being taken. E.g. for .c -> exe, the
result will be:

$ tcc -MD -o hello hello.c  # -> hello, hello.d
hello: \
        /usr/lib/crt1.o \
        /usr/lib/crti.o \
        hello.c \
        hello.h \
        /usr/include/stdio.h \
        /usr/include/features.h \
        /usr/include/bits/predefs.h \
        /usr/include/sys/cdefs.h \
        /usr/include/bits/wordsize.h \
        /usr/include/gnu/stubs.h \
        /usr/include/bits/wordsize.h \
        /usr/include/gnu/stubs-32.h \
        /home/kirr/local/tcc/lib/tcc/include/stddef.h \
        /usr/include/bits/types.h \
        /usr/include/bits/wordsize.h \
        /usr/include/bits/typesizes.h \
        /usr/include/libio.h \
        /usr/include/_G_config.h \
        /usr/include/wchar.h \
        /home/kirr/local/tcc/lib/tcc/include/stdarg.h \
        /usr/include/bits/stdio_lim.h \
        /usr/include/bits/sys_errlist.h \
        /usr/lib/libc.so \
        /lib/libc.so.6 \
        /usr/lib/ld-linux.so.2 \
        /lib/ld-linux.so.2 \
        /usr/lib/libc_nonshared.a \
        /lib/libc.so.6 \
        /usr/lib/libc_nonshared.a \
        /home/kirr/local/tcc/lib/tcc/libtcc1.a \
        /usr/lib/crtn.o \

So tcc dependency generator is a bit more clever than one used in gcc :)

Also, I've updated TODO and Changelog (in not-yet-released section).

v2:

(Taking inputs from grischka and me myself)

- put code to generate deps file into a function.
- used tcc_fileextension() instead of open-coding
- generate deps only when compilation/preprocessing was successful

v3:

- use pstrcpy instead of snprintf(buf, sizeof(buf), "%s", ...)
2010-06-21 20:49:02 +04:00
grischka
3ba37e1e3f tccgen: Revert yuanbin's recent patches
This reverts commits 670993..d35138
Maybe these commits fixed something but also seemed to cause problems.
2010-06-21 18:21:44 +02:00
Claudio Bley
433ecdfc9d implemented C99 for loop with variable declaration 2010-06-21 11:57:32 +02:00
Kirill Smelkov
bdae4a59c3 tcc: Refactor "compute default outfile name" into libtcc function
Since for upcoming -MD support default _compile_ output file be needed
even when preprocesssing (tcc -E), let's move this code out of one
particular condition block into a common function, so that we could use
it in deps generation code too.

v2:

- As suggested by grischka, moved into libtcc function instead of always
  computing near start of main()
- There is a FIXME about how to return result - I don't want to bother
  callers with allocating temp buffers, not I think it will be a good
  idea to hook default_target to TCCState. Clearly, I'm to used to
  things like std::string and python's str...
2010-06-20 21:36:47 +04:00
Kirill Smelkov
a919a373da Add input files/libs and reloc_output switch to TCCState
files[0], and reloc_outpu will be needed for (upcoming in the next
patch) "compute default outfile name" refactored into libtcc function.

Also, since for symmetry and from libification point of view, it makes
some sense to also put all information about what was given as input to
compilation into TCCState, let's not only put files[0], but all
files and all libraries given explicitely by user.

One point: I've used bitfield for reloc_output & trimmed down
output_type to 8 bits so that TCCState stays the same in size, and also
access to output_type is (hopefully) is not slower.

By the way -- as of today, sizeof(TCCState) on i686-pc-linux-gnu is 2884
bytes...
2010-06-20 20:30:01 +04:00
Kirill Smelkov
66b54af8ea tcc: Fix typo in error (it's '%s', not '%s) 2010-06-16 16:51:55 +04:00
Kirill Smelkov
87db8b637e chmod a-x i386-gen.c
No need to keep executable bit on plain C source.
2010-06-16 14:37:30 +04:00
grischka
632ee5a540 Revert "Complain for static fct declared w/o file scope"
This reverts commit e9406c09a3.

We don't want errors for static local function pointers, such as:
  {
    static void (*fn)();
    ...
  }
2010-06-15 17:03:23 +02:00
grischka
10b4802869 Fix "Fix bashims in configure ..." for MSYS
Fixes commit dc265feb63
2010-06-15 17:02:35 +02:00
grischka
5fcd1fef1c Fix last commits: remove CRLF, chmod 644 tccgen.c 2010-06-15 17:02:09 +02:00
yuanbin
d351384fdc tccgen: skip ')' in front of ',' for initializer 2010-06-13 14:50:53 +08:00
yuanbin
952e83e0ca tccgen: skip fields from same union 2010-06-13 02:37:28 +08:00
yuanbin
d6ce75b4d6 tccgen.c: skip fields from same union 2010-06-13 01:12:36 +08:00
Kirill Smelkov
5344b2e73b .gitignore += *.o *.a
Ignores libtcc.o, libtcc.a and a bunch of other files (see previous
patch for details)
2010-06-12 18:26:37 +04:00
Kirill Smelkov
de7a214c17 .cvsignore -> .gitignore
We no longer use CVS, so let's teach Git about what files to ignore...

... though doing `git status` after make + `make test` still gives
untracked content:

    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #       alloca86-bt.o
    #       alloca86.o
    #       bcheck.o
    #       libtcc.a
    #       libtcc.o
    #       libtcc1.a
    #       libtcc1.o
    #       tcc.o

See next patch about this stuff.
2010-06-12 18:18:19 +04:00
yuanbin
dd72577759 tccgen: initial the last member of union 2010-06-11 21:18:05 +08:00
yuanbin
6709933d78 tccgen: initial last member of union 2010-06-11 20:48:33 +08:00
Thomas Preud'homme
dc265feb63 Fix bashims in configure and gcctestsuite.sh.
configure and gcctestsuite.sh shell scripts contains bashisms although being
bourne shell script. This patch fixes the following bashisms:
* Use of $RANDOM variable (replaced by reading in /dev/urandom)
* Use == in tests instead of just =
* Use $[] for arithmetic computation istead of $(())
2010-05-26 14:08:29 +02:00
Daniel Glöckner
a867f42597 don't discard SHT_((PRE)INIT|FINI)_ARRAY sections 2010-05-15 01:26:56 +02:00
Daniel Glöckner
128e46f91b ARM: add support for R_ARM_V4BX 2010-05-15 01:23:34 +02:00
Daniel Glöckner
20a1cba286 ARM: implement rt_get_caller_pc 2010-05-14 14:22:32 +02:00
Daniel Glöckner
741841d863 ARM: allow jumps > 32MB on -run
This is needed to reach tinycc's PLT from the compiled program.
2010-05-14 13:07:59 +02:00
Daniel Glöckner
a64727ba7d append ULL to big constants 2010-05-13 22:18:33 +02:00
Daniel Glöckner
3de023b6c6 ARM: use uint32_t for opcodes
fixes cross compiling on x86_64
2010-05-13 22:17:09 +02:00
Daniel Glöckner
6eac6b7254 Revert "tccpp: Allow local labels to start with a dot"
This reverts commit f740485a5a.

It breaks access to structure elements starting with L
2010-05-06 21:42:37 +02:00
Thomas Preud'homme
8eb86ab78d Add nan, snan and inf float constants 2010-05-06 02:20:35 +02:00
Thomas Preud'homme
2220467fcf Don't load libtcc1 on arch where it doesn't exist
ARM architecture doesn't have any libtcc1 implementation but tcc load
libtcc1.a in all case. This patch add a conditional preprocessor
instruction to load libtcc1.a only when there is an implementation for
the target architecture.
2010-05-01 17:20:28 +02:00
Thomas Preud'homme
a28b18fa16 Link alias symbols together
Make sure alias symbols resolve to the same address in program .bss or .data
section. This ensure for example that if a program reference environ (via an
extern char **environ declaration) and the libc change its value via the
__environ alias after the R_ARCH_COPY relocation have been performed, then
the program will see the new value.
2010-05-01 16:45:36 +02:00
Henry Kroll III
036ff17916 reverse another unnecessary change
-m32 is set elsewhere now.
2010-04-29 23:52:20 -07:00
Henry Kroll III
1f62f2253c recursive Makefiles should use $(MAKE), not "make"
add clean: target for lib/tcc1.def
2010-04-29 23:06:23 -07:00
Henry Kroll III
c7a4e11bf1 remove superfluous LIBS=. (leftover from work on --disable-statc) 2010-04-28 16:15:19 -07:00
Henry Kroll III
209caeedee Summary of commits + added some brief comments to Makefile
Summary of what was changed or added so far:
    These won't work on Win32

* --disable-static option builds libtcca.so.1.0 and associated simlinks.
  This replaces libtcca.a, which is a static library with a dynamic one.

* --with-selinux option uses mmap to enable tcc -run to work with Selinux.

* attempt to build tcc1.def on i386 / x86_64 when --enable-cross is used.

  If successful, this gets around the "_start not found" or "_winstart not
  found" messages when i386-win32-tcc is run on these systems. I say "if"
  because it gave me fits of trouble on my system and not all others have
  been tested yet. tcc1.def is not a real .def file by the way, but it works,
  so it's kind of a dancing bear at this point. We're not concerned that
  it's getting the steps wrong. We're just happy it's not eating us for lunch.
2010-04-26 23:20:35 -07:00
Henry Kroll III
ac0b7d82d8 don't build tcc1.def on Windows.
I think the Windows build portion of the Makefile already
provides their own version. If not, we can remove the check.
2010-04-26 01:27:15 -07:00
Henry Kroll III
765992396f Makefile fixup:
* additional make target for lib/tcc1.def on non-win32 builds
  tcc1.def was formerly lib/libtcc1.a but has bee made into its
  own Makefile target, tcc1.def

* use mv instead of cp on config.h
  this fixes a mistake I made which caused Makefile to rebuild
  all targets every time

* make links from libtcc.so.1.0 to libtcc.so.1 and libtcc.so
2010-04-25 13:34:02 -07:00
Henry Kroll III
07eb850608 make --enable-cross work properly on x86_64
merge more changes from Fedora spec file into Makefile
I did a lot of reading on Makefiles. It should be a lot less hacked now that I got rid of my temporary cross-build script. I had to build i386-win32-tcc as 32 bit in order to use it to build the windows version of libtcc1.a and move that into lib directory. Still testing, but it does build windows fib.exe smoothly now and generates shard lib, libtcc.so.1.0 and test links against it.
2010-04-25 00:35:25 -07:00
Henry Kroll III
1a8e7d9fbb Merge branch 'mob' of ssh://repo.or.cz/srv/git/tinycc into makefile 2010-04-25 00:32:10 -07:00
Henry Kroll III
239fdf0b87 remove make_libtcc1_win32.sh shell script
and merge commands into Makefile
2010-04-24 22:16:39 -07:00
Henry Kroll III
eb78e94300 reverse make win32 version of libtcc1.a patch 2010-04-24 21:58:12 -07:00
Henry Kroll III
80b4c698c2 make win32 version of libtcc1.a for cross-compiler on x86 / x86_64 2010-04-24 13:27:56 -07:00
Henry Kroll III
b0b29d8013 put tcc in /usr/lib64/tcc on distros that have it 2010-04-24 03:30:46 -07:00
Henry Kroll III
2ab42855cb make --with-selinux work with libtcc, too 2010-04-24 03:28:54 -07:00
Henry Kroll III
a4ed587f61 add --disable-static option to build libtcc.so instead of libtcc.a
for distros that want static libs
2010-04-24 02:35:43 -07:00
Henry Kroll III
1578322b06 fix typo in configure 2010-04-24 02:32:41 -07:00
Henry Kroll III
4686236091 i386-win32-tcc fails to build a valid win32 executable if built
on x86_64 using --enable-cross. The easiest way to fix this is
to put -m32 in the Makefile.

Committer: Henry Kroll <henry@comptune.com>

Committer: Henry Kroll <henry@comptune.com>
2010-04-23 18:36:12 -07:00
Henry Kroll III
be7e339d8a Use mmap instead of exec mem for Selinux machines. Fixes crash on Fedora. 2010-04-20 23:43:02 -07:00
Thomas Preud'homme
a64a6f36a0 Replace malloc+strcpy by tcc_strdup in ld_load_file_list 2010-04-20 22:25:16 +02:00
Thomas Preud'homme
6525a15919 Fix "already done" test in libname_to_filename()
if "(libname == '\0')" should be instead "if (libname != '\0')"
2010-04-20 16:21:13 +02:00
Thomas Preud'homme
4d5fcfb971 Delete unused vtop_saved variable in unary_type 2010-04-20 16:12:41 +02:00
Thomas Preud'homme
3ad3168125 Clean changes introduced by 47abdbd
* Replace the save/load_buffer_state by a dynarray approach:
  - Filename and libname are added to a dynarray when first encountered
  - Load repeatedly the files in the dynarray until no new undefined
    symbol are encountered
* Replace snprintf by sprintf in libname_to_filename
* Use tcc_fileextension in filename_to_libname
* Introduce a tcc_strcpy_part fonction to copy only a subset of a
  string
* Move new_undef_syms declaration from tcc.h to tccelf.c
2010-04-20 16:02:42 +02:00
Timo VJ Lahde
809f489662 WinCE PE subsystem 2010-04-19 16:34:59 +03:00
Timo VJ Lahde
2cb1fd6a10 PE ARM: jump IAT arm code 2010-04-19 15:50:22 +03:00
Sergei Trofimovich
83b0bd3095 libtcc.c: fix compilation failure (inconsistent tcc_add_file_internal)
gcc -o libtcc1.o -c lib/libtcc1.c -O2 -Wall
libtcc.c: At top level:
libtcc.c:1063: error: static declaration of 'tcc_add_file_internal' follows non-static declaration
tccelf.c:2915: note: previous implicit declaration of 'tcc_add_file_internal' was here

Signed-off-by: Sergei Trofimovich <st@anti-virus.by>
2010-04-19 11:46:36 +03:00
Thomas Preud'homme
e4ed4e7f4f Support more arm EABI compatible architectures
Add support for:
  - armv5tel
  - armv6j
  - armv7a
2010-04-18 19:29:11 +02:00
Thomas Preud'homme
e9406c09a3 Complain for static fct declared w/o file scope
Error out on static function without file scope and give an explaination
to the user
2010-04-15 19:33:47 +02:00
Thomas Preud'homme
47abdbd3d5 Better handle ld scripts
* search file from INPUT and GROUP commands in the library path in
  addition to the current directory
* handle libraries specified by -lfoo options
* Search lib in GROUP command repeatedly
2010-04-15 19:30:00 +02:00
Thomas Preud'homme
6d4166df61 Don't prefix $prefix with $(DESTDIR) in configure
Prefixing $prefix with $(DESTDIR) is an error as it could lead for
example to mandir being equal to $(DESTDIR)$prefix/man where
$prefix itself is equal to $(DESTDIR)/usr/local which make man be equal
to $(DESTDIR)$(DESTDIR)/usr/local/man
2010-04-15 19:10:59 +02:00
Thomas Preud'homme
8de9b7a631 Correctly support all unary expression with sizeof
Unary expression can start with a parenthesis. Thus, the current test
to detect which sizeof form is being parsed is inaccurate. This patch
makes tcc able to handle things like sizeof (x)[1] where x is declared
as char x[5]; wich is a valid unary expression
2010-04-15 19:05:53 +02:00
Romain Francoise
6655e06ec8 Error out on bad char array initialization
Error out with an explicit message when trying to initialize a
character array with something that's not a literal (optionally
enclosed in braces) as per C99 6.7.8:14; thanks to Antti-Juhani
Kaijanaho <ajk@debian.org> who did all the work.
2010-04-15 19:04:25 +02:00
grischka
d2cf970a41 tccelf: fix warning 2010-04-13 18:30:01 +02:00
grischka
e6f43dd0c6 win32: sys/timeb.h use _ftime instead of _ftime32 2010-04-12 20:56:13 +02:00
Detlef Riekenberg
a3b932b3f9 tccgen: Fix broken use of ATTR_MODE
Sorry for that.

--
By by ... Detlef
2010-04-06 22:53:16 +02:00
Detlef Riekenberg
264a103610 tccgen: Detect (but ignore) function redirection
tcc is now able to parse <stdio.h> from gcc, when
__GNUC__ is also defined

--
By by ... Detlef
2010-04-06 00:33:15 +02:00
Detlef Riekenberg
34dabe496f libtcc: Detect (but ignore) -init and -fini for -Wl
--
By by ... Detlef
2010-04-05 22:56:33 +02:00
Detlef Riekenberg
87574de8ed libtcc: Support -soname for the linker
--
By  by ... Detlef
2010-04-05 21:37:54 +02:00
Detlef Riekenberg
78e83d8761 libtcc: Allow multiple options for -Wl separated with ','
I moved the code to libtcc to prepare for a later tiny_ld

--
By by ... Detlef
2010-04-05 21:21:58 +02:00
Detlef Riekenberg
a135dd50c6 tccasm: Detect (but ignore) .ident directive
tcc is now able to compile many asm files generated by gcc

--
By by ... Detlef
2010-04-05 12:45:52 +02:00
Detlef Riekenberg
558258a301 tccasm: Detect (but ignore) .size directive
--
By by ... Detlef
2010-04-05 12:43:51 +02:00
Detlef Riekenberg
6825c5db72 tccasm: Support .type directive (only name,@function)
--
By by ... Detlef
2010-04-05 12:31:45 +02:00
Detlef Riekenberg
f740485a5a tccpp: Allow local labels to start with a dot
--
By by ... Detlef
2010-04-05 12:28:27 +02:00
Detlef Riekenberg
9ff7a0bc98 tccasm: Detect (but ignore) the .file directive
Some patches, to allow tcc to compile asm sources generated by gcc
and help tcc with the autoconf stuff used in Wine
( http://source.winehq.org/git/wine.git/ )

--
By by ... Detlef
2010-04-05 12:19:49 +02:00
Timo VJ Lähde
197a6acb30 Avoid a crash with weak symbols for "make test"
Patch from the mailing list by Timo VJ Lähde

--
By by ... Detlef
2010-04-05 01:08:49 +02:00
U-UNIT1\dennis
d3c432244c generate inc and dec for smaller code 2010-04-03 21:20:34 +03:00
unknown
27bcc8f583 tinylibmaker: On error situation tempfile was not removed 2010-04-03 11:31:38 +03:00
Detlef Riekenberg
95bc36a149 tccpp: Add missing bracket in an error message 2010-03-31 00:42:39 +02:00
Daniel Glöckner
4d05a6319d Catch array[index] with unknown sizeof(*array)
We could support this for index == 0, but GCC doesn't bother, so why should we?
2010-03-15 22:51:19 +01:00
Manuel Simoni
95b9a477b6 weak function symbols 2010-02-27 17:37:59 +01:00
Ali Gholami Rudi
d63ec6f20d fill got table for static linking 2010-02-05 08:25:48 +03:30
Alexandre Becoulet
b9aeac0a64 Fixed bug which prevent tcc preprocessor to ignore line number directives 2010-02-01 18:08:51 +01:00
Nikos Mavrogiannopoulos
253bad7993 Added patch to detect and use the paths for 64bit libraries as
used by CentOS (affects X86_64 only).
2010-01-28 08:27:38 +01:00
Detlef Riekenberg
900871ca8d Dump the current token in skip(), when it's not the expected token 2010-01-27 00:02:33 +01:00
Detlef Riekenberg
62ba135228 Add support for --help 2010-01-26 22:58:48 +01:00
Detlef Riekenberg
a975008ae7 Add support for the __mode__ attribute
--
By by ... Detlef
2010-01-26 22:56:22 +01:00
Detlef Riekenberg
2650584ac4 Recognize -Wl,-Bsymbolic
Without -Bsymbolic, a symbol/function in a *.so can be overridden
by a symbol/function in the main module.
That is the default search order, but not supported by tcc.

With -Bsymbolic, the linker tries to resolve a symbol/function in
the current module first.
The loader in tcc implements this search order.

We do not distinguish -Bsymbolic and -Bsymbolic-function

--
By by ... Detlef
2010-01-26 22:55:14 +01:00
Detlef Riekenberg
5caf6235cf Makefile: Delete tcc-doc.html during 'make distclean' 2010-01-26 22:53:52 +01:00
grischka
3aa26a794e win32: adjust for mingw32 winapi packages
Note: the files in tcc/win32/include/winapi are now from the
mingw-w64 project, however with this fix using mingw32 winapi
should still work.
2010-01-26 22:18:03 +01:00
grischka
a40814cc9d tccpp: signal missing #endif error 2010-01-14 21:00:05 +01:00
grischka
4e5170d4a5 tccpp: convert TOK_GET macro into function 2010-01-14 20:59:44 +01:00
grischka
280e20b1d3 tccpp: warn about #define redefinition 2010-01-14 20:59:44 +01:00
grischka
e20bf69ac5 win64: defined size_t and ptrdiff_t to unsigned long long 2010-01-14 20:59:43 +01:00
grischka
b0abcfde9d win32: cleanup include 2010-01-14 20:59:43 +01:00
grischka
5299142286 x86-64: use uplong for symbol values 2010-01-14 20:59:42 +01:00
grischka
2341ee5142 tccpe: improve dllimport/export and use for tcc_add_symbol 2010-01-14 20:59:42 +01:00
grischka
bdb9387a74 win32: readme: add libtcc_test example 2010-01-14 20:59:41 +01:00
grischka
903b6001e7 update Makefiles 2009-12-20 20:34:35 +01:00
grischka
0de95730ad build from multiple objects: fix other targets 2009-12-20 20:33:41 +01:00
grischka
b54862406e x86-64: fix gtst, back to only 5 regs for now 2009-12-20 20:33:21 +01:00
grischka
070b86a870 x86-64: use r8/r9 as generic integer registers 2009-12-20 02:19:51 +01:00
grischka
0e5c0ee045 x86-64: use r8,r9 as load/store registers 2009-12-20 01:54:39 +01:00
grischka
cda8c41ef3 win32: add size_t to _mingw.h 2009-12-20 01:54:38 +01:00
grischka
4a01eb09d8 use vpushv in some places 2009-12-20 01:54:38 +01:00
grischka
50b040ef83 win64: add tiny unwind data for setjmp/longjmp
This enables native unwind semantics with longjmp on
win64 by putting an entry into the .pdata section for
each compiled fuction.

Also, the function now use a fixed stack and store arguments
into X(%rsp) rather than using push.
2009-12-20 01:54:37 +01:00
grischka
88a3ccab9f allow tcc be build from separate objects
If you want that, run: make NOTALLINONE=1
2009-12-20 01:53:49 +01:00
grischka
7fa712e00c win32: enable bounds checker & exception handler
exception handler borrowed from k1w1. Thanks.
2009-12-19 22:22:43 +01:00
grischka
8bbde91f62 tcc_relocate: revert to 0.9.24 behavior 2009-12-19 22:16:23 +01:00
grischka
3db219477a tccrun: new file
factor out -run support
2009-12-19 22:16:22 +01:00
grischka
41e112360f fix uninitialized warnings with 'type.ref' 2009-12-19 22:16:22 +01:00
grischka
3020a4765d tccpe: with -l try also with "lib" prefix
-lfoo searches: foo.def, libfoo.def, foo.dll, libfoo.dll
2009-12-19 22:16:21 +01:00
grischka
94bf4d2c22 tccpe: improve dllimport 2009-12-19 22:16:21 +01:00
grischka
1308e8ebcf integrate x86_64-asm.c into i386-asm.c
Also, disable 16bit support for now as it causes bugs
in 32bit mode.  #define I386_ASM_16 if you want it.
2009-12-19 22:16:20 +01:00
grischka
e81569bc70 tcc: add "-Wl,-rpath=path" option (library search path) 2009-12-19 22:16:20 +01:00
grischka
dd3d4f7295 x86-64: fix udiv, add cqto instruction 2009-12-19 22:16:19 +01:00
grischka
1445fea582 tccpe: allow linkage to extern symbols from asm 2009-12-19 22:16:18 +01:00
grischka
b5e2238483 tccasm: make VT_VOID symbols ST_NOTYPE, elf-wise
This was confusing objdump such that it did not print
disassembly with -d.

Also, put filename as with C compilation
2009-12-19 22:16:18 +01:00
grischka
ab4a4ab25e x86-64: in gv(): ignore second register 2009-12-19 22:16:17 +01:00
grischka
d79b867d55 win64: adjust for two args with setjmp(buf,ctx) 2009-12-19 22:16:17 +01:00
Christian Jullien
614790dc14 x86-64: Fix Wrong comparisonbetweenpointerandlongcste
main (int argc, char *argv[])
{
    char *p = (char *)0x12345678ABCD000F;
    int res;
    res = (p != (char *)0x12345678ABCD000F);
    return res;
}
2009-12-19 22:16:16 +01:00
grischka
e500c9118a i386-asm: fix imul
With imul the 3rd operand defaults to the 2nd on.  The previous
logic left 'op_type[2]' uninitialized which caused the bug to
show up only sometimes.
2009-12-06 17:41:22 +01:00
grischka
56d6abdb3d tccgen: propagate alignment from typedef
Store (part of) the AttributeDef structure in the (int)sym-r
field of the typedef symbol (kludgy).
2009-12-06 17:37:33 +01:00
bobbl
c0620c8a00 avoid needless register save when storing structures
When storing structs with a memcpy call in vstore(),
so far a needless entry remaining on the vstack
sometimes resulted in an useless store generated by
save_regs() in gfunc_call() for the memcpy routine.
2009-12-01 17:59:30 +01:00
Bernhard Reutner-Fischer
b573072300 document -print-search-dirs
Signed-off-by: aldot <rep.dot.nop@gmail.com>
2009-12-01 17:59:29 +01:00
Bernhard Reutner-Fischer
d2e125186f improve handling of --help
Previously ./configure --prefix=/foo --help didn't show the help-text

Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
2009-12-01 17:59:29 +01:00
Luigi Rizzo
55cb2170cd solve tccelf problem on FreeBSD
On Sun, Nov 22, 2009 at 05:43:14PM +0100, Luigi Rizzo wrote:
> Hi,
> there is a well known problem with tcc and FreeBSD in the generation
> of elf objects -- see
> http://lists.gnu.org/archive/html/tinycc-devel/2005-07/msg00070.html
>
> Apparently Sergey Lyubka has tried a partial fix to the problem.
> I was wondering if Sergey or someone can post some more detail on
> what needs to be done so we can try to help fixing this issue

I think i have managed to solve the problem and produce
almost valid elf files on FreeBSD. The two patches attached
address a few problems (trying to explain to the
best of my knowledge; i am not very familiar with ELF and
the FreeBSD ELF conventions):

1. ELF file format
  tcc produces an ELF executable which is good for linux but
  not for FreeBSD. It misses the PHDR section which is almost
  mandatory for shared executables, puts in the .dynsym section
  some relocation info that FreeBSD expects to be in .got,
  and expect the relocation sections to be contiguous.

  patch-tccelf.c tries to address the above problem using
  conditional sections (so hopefully can be imported upstream)
  and also adds the ability to override the name of the dynamic
  loader through an environment variable (this is important to
  debug tcc).

2. predefined macros

  patch-libtcc.c adds/fixes some predefined macros when compiling
  on FreeBSD: these are __FreeBSD__ and the usual set of
  __i386__ and __unix__ variants.
  It also sets __INTEL_COMPILER so we can grab the __aligned
  macro from cdefs.h , otherwise many programs would fail

The resulting elf file is still not 100% correct -- if you strip it,
the program will not run (presumably there is some dangling reference).
Other than that, program do seem to run correctly.

It would be nice to integrate these patches in the main repository.
The FreeBSD specific code is in #ifdef so it should not harm
linux users
	cheers
	luigi
2009-12-01 17:59:28 +01:00
grischka
720a32ede4 win32: remove #define alloca from mingw headers 2009-12-01 17:58:39 +01:00
grischka
679f0794f8 win32: explain usage of mingw w32api package 2009-11-30 17:14:41 +01:00
grischka
a5279b2c05 tccpe: fclose FILE*
Reported by Martin Ettl (thanks)
2009-11-30 17:14:37 +01:00
grischka
a26bf10de3 win64: Use tcc's own assembler
Now that we have it thanks to Mr. Féret
2009-11-21 23:43:38 +01:00
grischka
50055880f9 asm 32/64: replace (long)sym->next by sym->jnext 2009-11-21 23:43:30 +01:00
grischka
1383055b17 x86_64: fix asm 2009-11-14 21:48:37 +01:00
grischka
0a3bcb57f6 fix 32bit asm
The new 16bit code was causing wrong 0x66 prefixes
in 32bit code.

The fix possibly breaks the feature on 16bit asm.
2009-11-14 20:05:22 +01:00
Feret@.(none)
c15e37edad Removed binary executable output support
This broke writing executables.
2009-11-13 18:09:02 +01:00
Bernhard Reutner-Fischer
2fdb45f577 fix ambiguity
Signed-off-by: aldot <rep.dot.nop@gmail.com>
2009-11-13 18:09:02 +01:00
Frederic Feret
3065e70630 Fixed compilation error in i386-asm.c 2009-11-13 18:09:01 +01:00
Frederic Feret
ae23c46ce2 fixed and added missing file for x86_64 assembly 2009-11-13 18:09:01 +01:00
Frederic Feret
b7d7af4fa2 ARM: first support for arm-pe target 2009-11-13 18:09:00 +01:00
Frederic Feret
2f73e42d87 various fixes and new options for PE format 2009-11-13 18:09:00 +01:00
Frederic Feret
526c464504 first support of x86_64 assembly 2009-11-13 18:08:59 +01:00
Frederic Feret
0d768b9713 added 16-bit x86 assembly support 2009-11-13 18:08:58 +01:00
Frederic Feret
2349efa61b add binary executable output support 2009-11-13 18:08:58 +01:00
Daniel Glöckner
bc48cc1edb fix sizeof(array + integer)
Previously sizeof would return the size of the array although the
expression is always a plain pointer of 4 (or 8) bytes.
2009-11-13 18:05:15 +01:00
grischka
5b113f3ee3 win32: handle __declspec(dllimport) 2009-11-13 18:04:56 +01:00
grischka
dd70d19267 #define __TINYC__ = version-number 2009-11-13 17:11:52 +01:00
Shinichiro Hamaji
5dadff3de5 x86-64: Fix stab debug information.
We need 32bit relocations for code and 64bit for debug info.
Introduce a new macro R_DATA_PTR to distinguish the two usages.
2009-08-24 13:30:03 +02:00
Shinichiro Hamaji
3a1380120d x86-64: change the type of size_t and ptrdiff_t.
size_t and ptrdiff_t should be unsigned long and long, respectively.
2009-08-24 13:30:03 +02:00
grischka
834b782a9c tccpe: fill checksum header field 2009-08-24 13:30:02 +02:00
grischka
569c20f104 tccpp: fix quirk with cached headers and #else
Such as with

    #ifndef FOO_H
    ...
    #else
    ...
    #endif
2009-08-24 13:30:01 +02:00
grischka
1026ca5888 fix "symbol not defined" if symbol has offset 0 2009-08-24 13:30:01 +02:00
grischka
d923e652f2 tccpp: avoid double free with macro_ptr_allocated (after errors) 2009-08-24 13:30:00 +02:00
grischka
0d34c2136e tccgen: free inline functions correctly 2009-08-24 13:30:00 +02:00
grischka
697f9e305d win64: fix bat 2009-08-24 13:28:02 +02:00
grischka
b08dfb8273 tcc: optionally build using libtcc 2009-07-18 22:08:01 +02:00
grischka
f88350b611 fix some warning 2009-07-18 22:07:51 +02:00
grischka
c998985c74 cleanup: constify some global data 2009-07-18 22:07:42 +02:00
grischka
94ae3984b0 tccpe: set tcc_lib_path from DLL 2009-07-18 22:07:33 +02:00
grischka
1df662c1b0 tccpe: load dll on the fly 2009-07-18 22:07:25 +02:00
grischka
9fda4f4248 win32: treat long double as double 2009-07-18 22:07:17 +02:00
grischka
97738d1ae9 win32: reformat examples, crt etc 2009-07-18 22:07:10 +02:00
grischka
bb5e0df79a x86-64: fix load() for const pointers: (void*)-2 2009-07-18 22:07:03 +02:00
grischka
fc977d56c9 x86-64: chkstk, alloca 2009-07-18 22:06:54 +02:00
grischka
c0fc0fa0c4 win64: add x64 target to build-tcc.bat 2009-07-18 22:06:46 +02:00
grischka
dc251a7d8d win64: use new headers from mingw 2009-07-18 22:06:37 +02:00
grischka
06aed3d171 win64: update tiny_impdef, tiny_libmaker (Elf64) 2009-07-18 22:06:14 +02:00
grischka
09ac9faf59 win64: align jmp_buf 2009-07-18 22:06:07 +02:00
grischka
035918ef2f win64: fix pointer <-> unsigned long typecast issues 2009-07-18 22:05:58 +02:00
grischka
459875796b pe32+ target: adjust x86_64-gen.c
- calling conventions are different:
  * only 4 registers
  * stack "scratch area" is always reserved
  * doubles are mirrored in normal registers
- no GOT or PIC there
2009-07-18 22:05:49 +02:00
grischka
3ba1532cfb pe32+ target: add to makefile 2009-07-18 22:05:40 +02:00
grischka
3ea4acb9b9 pe32+ target: add in various #define's 2009-07-18 22:05:27 +02:00
grischka
719ba918dd tccpe: use more official structs 2009-07-18 21:55:32 +02:00
grischka
f366cb20fe tccpe: support pe32+ (x86_64) target 2009-07-18 21:55:28 +02:00
grischka
fe8def3303 tccpe: use ElfW macros 2009-07-18 21:55:25 +02:00
grischka
dcfad3af49 tccpe: get rid of kludgy export-symbol sort 2009-07-18 21:55:20 +02:00
grischka
370cdeb628 tccpe: build IAT vector with with -run too
This prepares for x86_64 where we need the vector
for far jumps.  Also, resolve DLL symbols in place
2009-07-18 21:55:15 +02:00
grischka
bed17847bd cleanup: stop abuse of sym->c for #define tokenstreams 2009-07-18 21:55:10 +02:00
grischka
d0b432ab38 cleanup: stop abuse of sym->r for inline functions 2009-07-18 21:55:06 +02:00
grischka
5e83b64dae cleanup: put prototypes in front of libtcc.c 2009-07-18 21:55:02 +02:00
grischka
85e481b66e pp: return newline after directive 2009-07-18 21:54:58 +02:00
grischka
fcdb663dde pp: simplify pasting, enable L ## number 2009-07-18 21:54:55 +02:00
grischka
045cff28fe fix asmtest (somehow), update Makefiles 2009-07-18 21:54:51 +02:00
grischka
0085c648f6 bcheck: restore malloc hooks when done 2009-07-18 21:54:47 +02:00
grischka
c93ddac9aa configure: support DESTDIR for RPM packagers etc.
Suggested by Shlomi Fish
2009-07-18 21:54:43 +02:00
grischka
ec4a350620 win32: guard va_list typedef 2009-06-17 02:11:40 +02:00
grischka
c4b7e77bbe accept option -x <lang> 2009-06-17 02:11:27 +02:00
grischka
610fd47510 win32: structure return GCC compatible (ret 4 with cdecl) 2009-06-17 02:11:13 +02:00
grischka
ec54c34b9e error messages: print "error: ..." 2009-06-17 02:10:56 +02:00
grischka
e4ae77c7bb tcc_preprocess: add gcc-style include-depth flags
# 1 "main.c"
    # 1 "include/stdio.h" 1
    # 123 "include/stdio.h" 3
    # 10 "main.c" 2

flags: 1: level++; 3: same-level  2: level--
2009-06-17 02:10:42 +02:00
grischka
956b4beec1 incompatible function ptr assignment: just warn
void fn_1(int i) {}
    void (*fn_2)(char*) = fn_1;
2009-06-17 02:10:24 +02:00
grischka
6a004ed19f allow redefinition of func_old_type functions
void *memcpy(void*, const void*, unsigned);

This gave an error if memcpy() has been used before
implicitely,  e.g. for structure passing etc.
2009-06-17 02:09:52 +02:00
Soloist Deng
c3701df16c trying to fix the bug of unclean FPU st(0)
Date: Mon, 8 Jun 2009 19:06:56 +0800
From: Soloist Deng <soloist.deng-gmail-com>
Subject: [Tinycc-devel] trying to fix the bug of unclean FPU st(0)

Hi all:

   I  am using  tcc-0.9.25, and the FPU bug brought a big trouble to
me. I read the source and tried to fix it.
Below is my solution.

 There are two places where program(`o(0xd9dd)') will generates `fstp
%st(1)': vpop() in tccgen.c:689 and save_reg() in tccgen.c:210.
We should first change both of them to `o(0xd8dd) // fstp %st(0)'.
But these changes are not enough.  Let's check the following code.

void foo()
{
 double var = 2.7;
 var++;
}

Using  the changed tcc will generate following machine code:

.text:08000000                 public foo
.text:08000000 foo             proc near
.text:08000000
.text:08000000 var_18          = qword ptr -18h
.text:08000000 var_10          = qword ptr -10h
.text:08000000 var_8           = qword ptr -8
.text:08000000
.text:08000000                 push    ebp
.text:08000001                 mov     ebp, esp
.text:08000003                 sub     esp, 18h
.text:08000009                 nop
.text:0800000A                 fld     L_0
.text:08000010                 fst     [ebp+var_8]
.text:08000013                 fstp    st(0)
.text:08000015                 fld     [ebp+var_8]
.text:08000018                 fst     [ebp+var_10]
.text:0800001B                 fstp    st(0)
.text:0800001D                 fst     [ebp+var_18]
.text:08000020                 fstp    st(0)
.text:08000022                 fld     L_1
.text:08000028                 fadd    [ebp+var_10]
.text:0800002B                 fst     [ebp+var_8]
.text:0800002E                 fstp    st(0)
.text:08000030                 leave
.text:08000031                 retn
.text:08000031 foo             endp
.text:08000031
.text:08000031 _text           ends
--------------------------------------------------
.data:08000040 ; Segment type: Pure data
.data:08000040 ; Segment permissions: Read/Write
.data:08000040 ; Segment alignment '32byte' can not be represented in assembly
.data:08000040 _data           segment page public 'DATA' use32
.data:08000040                 assume cs:_data
.data:08000040                 ;org 8000040h
.data:08000040 L_0             dq 400599999999999Ah
.data:08000048 L_1             dq 3FF0000000000000h
.data:08000048 _data           ends

Please notice the code snippet from 0800000A  to 08000020
// double var = 2.7; load constant to st(0)
.text:0800000A                 fld     L_0
// double var = 2.7; store st(0) to `var'
.text:08000010                 fst     [ebp+var_8]
// double var = 2.7; poping st(0)  will empty the floating registers stack
.text:08000013                 fstp    st(0)

  After that ,tcc will call `void inc(int post, int c)" in
tccgen.c:2150, and produce 08000015 to 0800001B through the calling
chain (inc ->gv_dup)
// load from `var' to st(0)
.text:08000015                 fld     [ebp+var_8]
// store st(0) to a temporary location
.text:08000018                 fst     [ebp+var_10]
// poping st(0)  will empty the floating registers stack
.text:0800001B                 fstp    st(0)

  And the calling chain
(gen_op('+')->gen_opif('+')->gen_opf('+')->gv(rc=2)->get_reg(rc=2)->save_reg(r=3))
will produce 0800001D to 08000020 .
// store st(0) to a temporary location, but floating stack is empty!
.text:0800001D                 fst     [ebp+var_18]
// poping st(0)  will empty the floating registers stack
.text:08000020                 fstp    st(0)

   The `0800001D   fst     [ebp+var_18]' will store st(0) to a memory
location, but st(0) is empty. That will cause  FPU invalid operation
exception(#IE).
Why does tcc do that? Please read `gv_dup' called by `inc' carefully.
Notice these lines:

(1):        r = gv(rc);
(2):        r1 = get_reg(rc);
(3):        sv.r = r;
            sv.c.ul = 0;
(4)         load(r1, &sv); /* move r to r1 */
(5)         vdup();
            /* duplicates value */
(6)         vtop->r = r1;

 (1)  let the vtop occupy TREG_ST0, and `r' will be TREG_ST0.  (2)
try to get a free floating register,but tcc assume
there is only one, so it wil force vtop goto memory and assign `r1'
with TREG_ST0. When executing (3), it will do nothing
because `r' equals `r1'. (5) duplicates vtop.  Then (6) let the new
vtop occupy TREG_ST0, but this will cause problem
because the old vtop has been moved to memory, so the new duplicated
vtop does not reside in TREG_ST0 but also
in memory after that. TREG_ST0 is not occupied but freely availabe
now.   `gen_op('+')'  need at least one oprand in register,
so it will incorrectly think TREG_ST0 is occupied by vtop and produce
instructions(0800001D and 08000020) to store it to
a temporary memory location.

  According program above, if `r' == `r1' it is impossible for the old
vtop to still occupy the `r' register .  And `load' will do nothing
too at this condition.
So the `gv_dup' can not promise the semantics that old vtop in one
register and the new duplicated vtop in another register at the same
time.

  I changed (6) to
if (r != r1)
{
 vtop->r = r1;
}

  Then the new generated machine code will be :

.text:08000000                 push    ebp
.text:08000001                 mov     ebp, esp
.text:08000003                 sub     esp, 10h
.text:08000009                 nop
.text:0800000A                 fld     L_0
.text:08000010                 fst     [ebp+var_8]
.text:08000013                 fstp    st(0)
.text:08000015                 fld     [ebp+var_8]
.text:08000018                 fst     [ebp+var_10]
.text:0800001B                 fstp    st(0)
.text:0800001D                 fld     L_1
.text:08000023                 fadd    [ebp+var_10]
.text:08000026                 fst     [ebp+var_8]
.text:08000029                 fstp    st(0)
.text:0800002B                 leave
.text:0800002C                 retn

 It works well, and will clean the floating registers stack when return.
 Finally, I want to know there is any potential problem of this fixing ?

soloist
2009-06-17 02:09:26 +02:00
grischka
a342bbadc8 use static declaration from prototype
static int func();
    ...
    int func() { }

As result, func needs to be static.
2009-06-17 02:09:20 +02:00
grischka
69fdb57edd unions: initzialize only one field
struct {
      union {
        int a,b;
      };
      int c;
    } sss = { 1,2 };

This had previously assigned 1,2 to a,b and 0 to c which is wrong.
2009-06-17 02:09:07 +02:00
grischka
bba515afe5 tccelf: accept BSS symbol with same name from other module
... such as 'int baz;' in two files at the same time
2009-06-17 02:08:54 +02:00
Sam Watkins
e7297581fc pass constness from structs to members 2009-06-16 04:26:44 +08:00
Shinichiro Hamaji
dca2b15df4 x86-64: Align return value of alloca by 16. 2009-06-11 08:33:41 +09:00
Shinichiro Hamaji
8ea8305199 x86-64: Add alloca. 2009-06-09 03:23:08 +09:00
grischka
110a4edc15 drop alloca #define
(Because GNU's alloca.h unconditionally #undef's alloca)

Also, remove gcc specific sections in headers. and
instead change tests such that gcc does not use them.
2009-05-16 22:30:13 +02:00
grischka
68310299b6 ulibc: #define TCC_UCLIBC and load elf_interp 2009-05-16 22:29:40 +02:00
grischka
bf8d8f5f3e update Changelog, bump version: 0.9.25 2009-05-11 19:01:26 +02:00
grischka
aed6a7cb60 fix "cached include" optimization
comparing the filenames as in the #include statement can be
ambiguous if including files are in different directories.

Now caches and checks the really opened filename instead.
2009-05-11 18:55:16 +02:00
Daniel Glöckner
530b77e365 ARM: fix big immediate offset construction
The loop constructs to iterate over the non-overlapping, even
positions of two or three bytes in a word were broken.

This patch fixes the loops. It has been verified to generate the
72 combinations for two and the 80 combinations for three bytes.
2009-05-11 18:54:14 +02:00
grischka
ca4b4a52ad fix build with msvc 2009-05-11 18:53:52 +02:00
grischka
03c787d6ce fix unused/uninitalized warnings 2009-05-11 18:46:39 +02:00
grischka
40f5ce002e fix warnings with tcc_add/get_symbol 2009-05-11 18:46:25 +02:00
grischka
67aebdd5b7 enable making tcc using libtcc 2009-05-11 18:46:02 +02:00
grischka
0a35f9d66e move static prototypes to libtcc.c 2009-05-11 18:45:56 +02:00
grischka
f9181416f6 move some global variables into TCCState 2009-05-11 18:45:44 +02:00
grischka
5c6509578e make tcc from tcc.c and libtcc from libtcc.c 2009-05-05 20:41:17 +02:00
grischka
b8f6e1ae30 move minor things from libtcc.c to other files 2009-05-05 20:30:39 +02:00
grischka
92204e8818 move global variables to libtcc.c 2009-05-05 20:30:13 +02:00
grischka
9dc9cbf319 move libtcc interface and helper functions to libtcc.c 2009-05-05 20:18:53 +02:00
grischka
0d1ed74102 move parser/generator to tccgen.c 2009-05-05 20:18:10 +02:00
grischka
805990b94e move preprocessor to tccpp.c 2009-05-05 20:17:49 +02:00
grischka
ae37bd5abc move declarations to tcc.h 2009-05-05 20:17:26 +02:00
grischka
a93bcdffae new files: tcc.h libtcc.c tccpp.c tccgen.c 2009-05-05 20:17:11 +02:00
grischka
15626621fb cleanup makefiles 2009-04-19 21:24:32 +02:00
grischka
e9e89ad699 enable backtrace only when it's supported 2009-04-18 18:39:27 +02:00
Shinichiro Hamaji
859da934e0 Return value of exit should be void. 2009-04-18 23:55:51 +09:00
Shinichiro Hamaji
48ae0c0468 Fixes for tests/Makefile.
- On x86-64, we need $(TARGET) in RUN_TCC.
- s/RuN_TCC/RUN_TCC/
2009-04-18 23:53:25 +09:00
grischka
5829791ffa fix makefiles etc for subdirs 2009-04-18 15:08:03 +02:00
grischka
ea5e81bd6a new subdirs: include, lib, tests 2009-04-18 15:08:03 +02:00
grischka
e8a52a8249 win32: readme.txt->tcc-win32.txt, update tcc-doc 2009-04-18 15:08:03 +02:00
grischka
eca1fbaf92 mute strange difference in tcctest 2009-04-18 15:08:03 +02:00
grischka
b56f956247 libtcc: add support to be build as DLL 2009-04-18 15:08:03 +02:00
grischka
d165e87340 libtcc: new api tcc_set_lib_path 2009-04-18 15:08:03 +02:00
grischka
73ba078d2f tcc_relocate: return error and remove unused code 2009-04-18 15:08:03 +02:00
Shinichiro Hamaji
d36fea34e3 Call relocate_sym() before we return the offset, so user doesn't need to check the return value twice. 2009-04-18 15:08:03 +02:00
grischka
dd5630ff95 tcc -E: fix pasting empty tokens
/* test case */
#define t(x,y,z) x ## y ## z
int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
        t(10,,), t(,11,), t(,,12), t(,,) };

tcc -E: xpected result:
int j[] = { 123, 45, 67, 89,
 10, 11, 12, };
2009-04-18 15:08:02 +02:00
grischka
0f0ed4a8bf tcc -E: preserve spaces, alternative solution
/* test case */
#define STR(x) #x
#define MKSTR(x) STR(x)
MKSTR(-A-)
MKSTR(+ B +)

tcc -E: expected result:
"-A-"
"+ B +"
2009-04-18 15:08:02 +02:00
grischka
90697c4c56 CONFIG_TCC_STATIC: add dummy for dlclose 2009-04-18 15:08:02 +02:00
grischka
d62301b050 avoid warning uninitialized 2009-04-18 15:08:02 +02:00
Shinichiro Hamaji
9a7173bf69 x86-64: Fix tcc -run. We need extra memory for PLT and GOT.
Size of the extra buffer is too large for now.
2009-04-18 15:08:02 +02:00
grischka
e6ba81b012 get rid of 8 bytes memory leak 2009-04-18 15:08:02 +02:00
grischka
b1697be691 change tcc_add/get_symbol to use void* 2009-04-18 15:08:02 +02:00
grischka
795f67428e alternative int tcc_relocate(TCCState *s1, void *ptr); 2009-04-18 15:08:02 +02:00
grischka
9a8b2912ed TOK_builtin_malloc: alternative solution 2009-04-18 15:08:02 +02:00
Shinichiro Hamaji
742cf05875 x86-64: Define make variable TARGET so that test2 and test3 use correct flag. 2009-04-18 15:08:02 +02:00
Shinichiro Hamaji
85d016b507 x86-64: Remove code for debug print.
Now, we concat buffers before relocation. So this only happens when users try creating >2GB binary.
2009-04-18 15:08:02 +02:00
Shinichiro Hamaji
39a4b859d4 x86-64: Fix cast from integers to pointers.
Now,

./tcc -run -DTCC_TARGET_X86_64 tcc.c -run tcctest.c

works!
2009-04-18 15:08:02 +02:00
Shinichiro Hamaji
51a7f163ad Work around for the issue TCC doesn't handle -2147483648 properly.
TCC produces code which is incompatible with GCC for the following code:

    printf("%lld\n", (long long)-2147483648);
    printf("%lld\n", (long long)-2147483649);

For now, just avoid using the corner value.
2009-04-18 15:08:01 +02:00
Shinichiro Hamaji
83fd36333a Fixes for issues I've just found/introduced to x86 TCC.
- Cast from pointer to long long makes TCC output an error. Use cast to int before we apply shift operation for a pointer value.
- Removed test cases for casts from pointer to char/short because they produce warning.
2009-04-18 15:08:01 +02:00
Shinichiro Hamaji
be43c8e0ed x86-64: Cast from 64bit pointer to long long must not generate movslq. 2009-04-18 15:08:01 +02:00
grischka
a9c78d04f2 win32: accept uppercase filename suffixes 2009-04-18 15:08:01 +02:00
Shinichiro Hamaji
b879ffa193 x86-64: There can be valid addresses which is greater than 0xc0000000. 2009-04-18 15:08:01 +02:00
Shinichiro Hamaji
de3f0a46fe Fix for x86-64: The first and second arguments of memcpy must be pointers. 2009-04-18 15:08:01 +02:00
Shinichiro Hamaji
2e9b57b6d0 Fix silly typos in the previous change. 2009-04-18 15:08:01 +02:00
Shinichiro Hamaji
9fe28b610e x86-64: Make ABI for long double compatible with GCC.
- Now we use x87's stack top the long double return values.
- Add rc_fret and reg_fret, wrapper functions for RC_FRET and REG_FRET.
- Add a test case to check if strto* works OK.
2009-04-18 15:08:01 +02:00
Shinichiro Hamaji
0e239e2ba5 Improve the test coverage: !val for float/double/long long f. 2009-04-18 15:08:01 +02:00
Shinichiro Hamaji
fcf2e5981f x86-64: Combine buffers of sections before we call tcc_run().
- Now we can run tcc -run tcc.c successfully, though there are some bugs.
- Remove jmp_table and got_table and use text_section for got and plt entries.
- Combine buffers in tcc_relocate().
- Use R_X86_64_64 instead of R_X86_64_32 for R_DATA_32 (now the name R_DATA_32 is inappropriate...).
2009-04-18 15:08:01 +02:00
Shinichiro Hamaji
830b7533c9 Generate PIC code so that we can create shared objects properly.
- Add got_table in TCCState. This approach is naive and the distance between executable code and GOT can be longer than 32bit.
- Handle R_X86_64_GOTPCREL properly. We use got_table for TCC_OUTPUT_MEMORY case for now.
- Fix load() and store() so that they access global variables via GOT.
2009-04-18 15:08:01 +02:00
grischka
6c10429aa5 check for absolute include paths
Suggested by Sandor Zsolt <narkoskatona@yahoo.com>
2009-04-18 15:07:28 +02:00
grischka
29c8e1545a get rid of "free_section problem" with private sections 2009-04-18 15:07:28 +02:00
grischka
c80f81c199 tiny_libmaker: fix function array overflow 2009-04-18 15:07:28 +02:00
grischka
5818945ef6 accept "restrict" in array-decl (STDC 199901) 2009-04-18 15:07:27 +02:00
grischka
0e015988cc i386: apply "align=8 for doubles ..." for PE only 2009-04-18 15:07:27 +02:00
Shinichiro Hamaji
97072b3cd7 x86-64: Now TCC can create healthy shared objects from object files generated by GCC
- Handle R_X86_64_GOTPCREL.
- Output R_X86_64_RELATIVE reloc generated from R_X86_64_64.
2009-04-18 15:07:10 +02:00
Shinichiro Hamaji
754b0beb7d x86-64 bug fix: Fix stab generation for x86-64.
The size of a stab entry is 12 bytes even in 64bit environments. We must use int instead of long to keep the size of stab entries.
2009-04-18 15:07:09 +02:00
Shinichiro Hamaji
e6db5f5fb6 x86-64 bug fix: Use stack with alignment just like 32bit environments. 2009-04-18 15:07:09 +02:00
Shinichiro Hamaji
06fa15fb99 x86-64: Save RDX and RCX before we use them as function parameters.
When the function call is indirect, these registers may be broken to load a function pointer.
2009-04-18 15:07:09 +02:00
Shinichiro Hamaji
ebb874e216 Remove multiple definition error caused by combination of x86-64 and va_list.
We need malloc and free to implement va_start and va_end.
Since malloc and free may be replaced by #define, we add __builtin_malloc and __builtin_free.
2009-04-18 15:07:09 +02:00
Shinichiro Hamaji
6512d9e2ea Add check for invalid numbers.
If there are some characters after TCC parses a number, it is an error.

This bug was reported on list:

http://www.mail-archive.com/tinycc-devel@nongnu.org/msg02014.html
2009-04-18 15:07:09 +02:00
Shinichiro Hamaji
af6cbc48d1 Fix overrun in decl_initializer_alloc.
This bug was reported on

http://lists.gnu.org/archive/html/tinycc-devel/2009-03/msg00035.html

This happens because parser of array initializer doesn't stop to read until semi-colon or comma.
2009-04-18 15:07:09 +02:00
Shinichiro Hamaji
040ef000e4 Better DLL support on x86-64.
- Add a macro TCC_OUTPUT_DLL_WITH_PLT.
-- Now, the DLL with PLT support works only on x86-64, but we may be able to support it on all architectures eventually.
- Define TCC_OUTPUT_DLL_WITH_PLT when target architecture is x86-64.
- Current status (x86-64):
-- Main program should be able to call functions in shared objects.
-- Main program should be able to use global variables in shared objects.
-- Shared objects should be able to call functions in main  program.
-- Shared objects can NOT use global variables in main program.
- To fix the last issue, we may need to add support of -fPIC option in our code generator.
2009-04-18 15:07:09 +02:00
Shinichiro Hamaji
fe8f230ab6 First naive DLL support on x86-64.
This logic depends on x86_64-gen.c and doesn't work with objects compiled by GCC.
2009-04-18 15:07:09 +02:00
Shinichiro Hamaji
b8a32d8d40 Generate PIC for addresses of symbols. 2009-04-18 15:07:09 +02:00
Shinichiro Hamaji
7db1e69df2 Suppress noisy pointer signed-ness warnings on x86-64. 2009-04-18 15:07:09 +02:00
Shinichiro Hamaji
006c907da7 Code cleaning: utilize vpushll(). 2009-04-18 15:07:09 +02:00
Shinichiro Hamaji
4f056031f4 Support long long bitfields for all architectures.
- Modified gv() and vstore(), added vpushll().
- Added a test case for long long bitfields.
- Tested on x86 and x86-64.
2009-04-18 15:07:09 +02:00
Shinichiro Hamaji
62e73da612 A uint64 bug fix on x86-64
64bit unsigned literal was handled as 32bit integer.
Added a unittest to catch this.
2009-04-18 15:07:08 +02:00
Shinichiro Hamaji
ae607280c5 Allow long long as a type of bitfields on x86-64. 2009-04-18 15:07:08 +02:00
grischka
4a8c2229ce win32: allow user segments as writable & executable 2009-04-18 15:07:08 +02:00
grischka
3116744bdd i386: align=8 for double and long long 2009-04-18 15:07:08 +02:00
grischka
b41fc95566 win32: fix for VC8Express compiler 2009-04-18 15:07:08 +02:00
Kirill Smelkov
00f0932760 tcc -E: preserve spaces (partial solution)
Recently I needed to trim storage space on an embedded distro which has
X.

X depend on cpp which is ~8MB in size as shipped in Debian, so the idea
was to remove cpp and use `tcc -E` instead where appropriate.

I've done this with the following 'hack' put inplace of /usr/bin/cpp :

    #!/bin/sh -e
    TCC=/home/kirr/local/tcc/bin/tcc
    last="${!#}"

    # hack to distinguish between '... -D...'  and '... file'
    if test -r "$last"; then
        exec $TCC -E "$@"
    else
        exec $TCC -E "$@" -
    fi

But the problem turned out to be in `tcc -E` inability to preserve
spaces between tokens. So e.g. the following ~/.Xresources

    XTerm*VT100*foreground: black
    ...

got translated to

    XTerm * VT100 * foreground : black

which is bad, bacause now X don't understand it.

Below is a newbie "fix" for the problem.

It still does not preserve spaces on macro expansion, but since the fix
cures original problem, I think it is at least one step forward.

Signed-off-by: Kirill Smelkov <kirr@landau.phys.spbu.ru>
2009-04-18 15:07:08 +02:00
Kirill Smelkov
6213d4b4b6 string_test: we should always use 'unsigned int' for b
As recently shown in fb0ac2 (s/int/unsigned/ since GCC 4.3.2 produces
code which doesn't stop)

comparing (signed) int variable to 0x80000000 is not idea for x86_64.

This is not a good idea for x86_32 either, because GCC 4.3.2 (the one in
Debian Lenny) rightly assumes that a signed int could be never
0x80000000, and thus removes the check from

    while (b != 0x80000000) {
        ...

completely.

If we want this check, we need b to be always 'unsigned'

Signed-off-by: Kirill Smelkov <kirr@landau.phys.spbu.ru>
2009-04-18 15:07:08 +02:00
Alexander Egorenkov
5a044b67bb type_size function returned incorrect size
of multi dimensional arrays if dimension is divisable by 2
2009-04-18 15:07:08 +02:00
grischka
64147b346b fix constant optimization for unsigneds 2009-04-18 15:07:08 +02:00
grischka
7c3f19c079 fix data overflow with init_putv
The simplest code to reproduce this bug seems to be
    int a[][] = {{1,1,1,1,1,1,1}};
2008-12-02 02:36:27 +01:00
Shinichiro Hamaji
aa8d22e38e Add several test cases. 2008-12-02 02:32:52 +01:00
Shinichiro Hamaji
0a9873aa22 Add support of x86-64.
Most change was done in #ifdef TCC_TARGET_X86_64. So, nothing should be broken by this change.

Summary of current status of x86-64 support:

- produces x86-64 object files and executables.
- the x86-64 code generator is based on x86's.
-- for long long integers, we use 64bit registers instead of tcc's generic implementation.
-- for float or double, we use SSE. SSE registers are not utilized well (we only use xmm0 and xmm1).
-- for long double, we use x87 FPU.
- passes make test.
- passes ./libtcc_test.
- can compile tcc.c. The compiled tcc can compile tcc.c, too. (there should be some bugs since the binary size of tcc2 and tcc3 is differ where tcc tcc.c -o tcc2 and tcc2 tcc.c -o tcc3)
- can compile links browser. It seems working.
- not tested well. I tested this work only on my linux box with few programs.
- calling convention of long-double-integer or struct is not exactly the same as GCC's x86-64 ABI.
- implementation of tcc -run is naive (tcc -run tcctest.c works, but tcc -run tcc.c doesn't work). Relocating 64bit addresses seems to be not as simple as 32bit environments.
- shared object support isn't unimplemented
- no bounds checker support
- some builtin functions such as __divdi3 aren't supported
2008-12-02 02:30:47 +01:00
Shinichiro Hamaji
fb0ac27691 s/int/unsigned/ since GCC 4.3.2 produces code which doesn't stop. 2008-12-02 02:26:42 +01:00
Shinichiro Hamaji
1e776b29d3 Suport LDOUBLE_SIZE == 16 environment. 2008-12-02 02:26:40 +01:00
Shinichiro Hamaji
ba8c95a98d silly bug fix: s/#ifdef PTR_SIZE == 4/#if PTR_SIZE == 4/ 2008-12-02 02:26:37 +01:00
Shinichiro Hamaji
27d23342ea Make tccelf.c 64bit ready.
- Use REL_SECTION_FMT instead of ".rel%s".
- Use PTR_SIZE instead of sizeof(int) for GOT entries.
- Use sizeof(ElfW(Dyn)) instead of magic number 8.
- Use TCC_ELFCLASS instead of ELFCLASS32.
2008-12-02 02:26:34 +01:00
Shinichiro Hamaji
c92daa02e4 One more s/int/long/ 2008-12-02 02:26:11 +01:00
Shinichiro Hamaji
ce8d71edbc Use int*2 instead of long*2 to hold double value.
I believe sizeof(double) is sizeof(int)*2 in most environments. On the other hand, sizeof(long) is equal to sizeof(double) in x86-64.
2008-12-02 02:26:07 +01:00
Shinichiro Hamaji
2355fc7686 Use long instead of int to hold pointer values. 2008-12-02 02:26:03 +01:00
Shinichiro Hamaji
d6072d3703 Add __builtin_frame_address(0)
Adding the GCC extension __builtin_frame_address(). We support only zero as the argument for now.
With this functionality, we can implement GCC compatible stdarg by macros in x86-64.
2008-12-02 02:25:59 +01:00
Shinichiro Hamaji
73a84cefda Imported several macros required by x86-64 2008-12-02 02:25:54 +01:00
Shinichiro Hamaji
7dd792ef51 Introduce ElfW macro and ELFW to encapsulate the difference between Elf32_* and Elf64_*. Also, introduce ElfW_Rel and SHT_RELX for difference between REL and RELA. 2008-12-02 02:25:45 +01:00
Daniel Glöckner
76b02c2a03 Futher changes to casts
nocode_wanted can't be used to enforce constant expressions, as it is
set f.ex. by __builtin_constant_p.

A null pointer is unequal to a pointer to any object or function.
Assuming symbols always point to memory, a symbol+constant cast to bool
is always true.
2008-11-30 07:21:49 +01:00
Daniel Glöckner
5fd6f7bd44 Fix get_tok_str wrt wide characters
Fixes both, character constants and string literals.
2008-11-30 07:21:46 +01:00
Daniel Glöckner
deb410710c Rewrote '?' for constants
The condition is now cast to _Bool and it now works with return
types bigger than 32 bit.
2008-11-30 07:21:42 +01:00
Daniel Glöckner
1b599ea7f8 Cast parameter of '!' to _Bool 2008-11-30 07:21:35 +01:00
Daniel Glöckner
2d9b5e0bb8 Rewrote casts
Casting of constants was done only inside functions.
I restructured the code and used intermediate types (long double/long long)
for most conversions to have less ifs.

Please review.
There are lots of cases to take care of and lots of mistakes to make.
2008-11-30 07:21:30 +01:00
grischka
83466c6151 line-numbers output for TCC -E 2008-11-30 07:21:01 +01:00
grischka
78f288bc87 win32/build-tcc.bat: define CONFIG_SYSROOT 2008-11-30 03:16:43 +01:00
grischka
7bebf1f59a was hash, not link 2008-09-15 02:07:55 +02:00
grischka
7f51aa13e7 update changelog 2008-09-15 00:12:10 +02:00
Daniel Glöckner
a80acab4fc Display error on statement expressions with complex return type
The return type of a statement expression (a GCC extention) may
involve elements on the symbol stack that have been put there by
the expression. These will be freed at the end of the expression
so that the calling block can not use them.

Contrary to the comment (written in 2003), this bug no longer shows
up in Valgrind, as freed symbols are now put onto a stack for later
reuse.
2008-09-12 22:23:02 +02:00
Daniel Glöckner
3783b33508 Fix bitfields with non-int types and in unions
The ISO C draft allow only signed/unsigned int and _Bool as base type
for bitfields. TinyCC ever since allowed a wider range of types, but
there were many bugs that shifted values when they shouldn't, etc..
The patch introduces a restriction to the layout of bitfields with
mixed types that makes it incompatible with GCC. In

struct {
  typeA x:1;
  typeB y:1;
};

y is combined with x in the same byte iff typeA is typeB (neglecting
signedness). This is done to avoid alignment issues and exceeding the
width of typeA.
2008-09-12 22:23:01 +02:00
Daniel Glöckner
43a34d354a Force null pointer exception for code outside of a function
TinyCC sometimes has problems to evaluate constant expressions at
compile time. This leads to code being generated outside of functions.
Without this patch some of these bugs are not caught, because
cur_text_section still points to the section of the last function.
Before the first function cur_text_section is uninitialized.
Setting cur_text_section to a null pointer should make TinyCC die in
all cases.
2008-09-12 22:23:00 +02:00
Daniel Glöckner
5a92536cea Optimize arithmetic with pointer to value on stack + constant 2008-09-12 22:23:00 +02:00
Daniel Glöckner
e263ee3cbf Fix gv for long longs
long long a();
long long b() {
  return a();
}

At the end of b there will be some useless register shuffling.
This is because return wants to have the result of a in REG_IRET.
gv checks if this is the case for BOTH registers of the long long.
After this test it uses REG_LRET for the second register if the
first is supposed to be REG_IRET. In other cases it uses RC_INT.

The patch compares the second register against the class it will
have in the end instead of the register class the first register
will have.

At this point I would like to remind those who pick up the patches
that there are two other mails by me with uncommitted fixes:
http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html
http://lists.gnu.org/archive/html/tinycc-devel/2008-08/msg00007.html

  Daniel
2008-09-12 22:22:59 +02:00
Daniel Glöckner
15e0dc08a6 Allow to use libgcc instead of libtcc1
This patch adds a switch --with-libgcc to configure.
When passed it prevents libtcc1.a from being built and links to
/lib/libgcc_s.so.1 instead of PREFIX/lib/tcc/libtcc1.a.

It will work on ARM when using libgcc from GCC >= 4.2.0.
Prior versions don't have the __floatun[sd]i[sdx]f functions.

It won't work on i386 because of two missing symbols emitted when
floats are cast to integers, but users can provide those symbols
(global short constants) in their code if needed.

  Daniel
2008-09-12 22:22:58 +02:00
Daniel Glöckner
256f6e6200 A prefix for default library/include search paths
This patch is useful for cross compilers. Without this patch tcc
tries to use the host's libraries, crt*.o and include files.
The patch prepends a string to all default paths. The string can
be passed to configure with --sysroot=string.

  Daniel
2008-09-12 22:22:58 +02:00
Daniel Glöckner
e8039673ad ARM related Makefile changes
- Builds all four possible ARM targets when cross compiling

- Adds some auto detection to select the target for native ARM builds

The auto detection will select EABI if it finds /lib/ld-linux.so.3.
It will select VFP floating point support when /proc/cpuinfo lists
a VFP or iWMMXt coprocessor. Intel Wireless MMX does not imply VFP,
but it conflicts with FPA, so VFP is the only choice (apart from
yet unsupported soft-float).

  Daniel
2008-09-12 22:22:57 +02:00
Daniel Glöckner
12265da6cd Runtime lib functions
Yesterday I felt the urge to change a few things in TinyCC.
This is the first and biggest change of all of them.

- use __aeabi_*divmod functions in ARM EABI to make binaries depend
  solely on standardized library functions

- refactor ARM floating point <-> integer conversion a bit

- rename long long->float and shift library functions to correspond to
  the names used by GCC

- compile more tokens conditionally to reduce the size of TinyCC

The intention is primarily to allow users of the ARM target to use
libgcc (which is usually available as a shared library) instead of
libtcc1 (which can't be compiled for ARM due to lack of an inline
assembler).

Changing the EABI target to use the divmod functions in theory allows
to use it without libtcc1 on any (not necessarily GCC based) ARM EABI
system.

  Daniel
2008-09-12 22:22:36 +02:00
Daniel Glöckner
2c657f6608 Set VT_LVAL_xxx flags for function arguments in gfunc_prolog (Daniel Glöckner) 2008-09-12 02:36:32 +02:00
Adam Sampson
8f7e3f325d Patch for DESTDIR installation (Adam Sampson) 2008-09-12 02:36:26 +02:00
grischka
2c6cd08bcc fix isidnum_table for CH_EOF (-1) 2008-09-12 02:36:05 +02:00
grischka
1300cec38c free_section bugfix 2008-09-12 02:36:01 +02:00
grischka
f9bf48d643 release loaded dlls cleanly (Sam K) 2008-05-05 22:40:49 +00:00
grischka
96bd8f2b25 enable pe-output from libtcc (Shmuel Zeigerman) 2008-05-05 22:39:43 +00:00
grischka
f2698687fb fix options in C scripts after -run 2008-04-27 18:50:35 +00:00
grischka
5247bbc2f0 fix stabstr with linked objects 2008-04-27 18:49:31 +00:00
grischka
0d598aca08 fix bogus relocations with TCC_OUTPUT_DLL 2008-04-27 18:48:19 +00:00
grischka
23594b6980 enable multiple states and fix minor memory leaks 2008-04-27 18:47:35 +00:00
558 changed files with 126311 additions and 39779 deletions

View File

@ -1,37 +0,0 @@
tcc_g
tcc
tc2.c
doc
tc3s.c
p3.c
tc1.c
error.c
i386-gen1.c
test.out2
test.out3
web.sh
memdebug.c
bench
Makefile.uClibc
boundtest
prog.ref
test.ref
test.out
tcc-doc.html
ideas
tcctest.ref
linux.tcc
ldtest
libtcc_test
instr.S
p.c
p2.c
tcctest[1234]
test[1234].out
.gdb_history
tcc.1
tcc.pod
config.h
config.mak
config.texi
tests

143
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,143 @@
name: build and test
on:
push:
branches: [ mob ]
jobs:
test-x86_64-linux:
runs-on: ubuntu-22.04
timeout-minutes: 2
steps:
- uses: actions/checkout@v4
- name: make & test tcc (x86_64-linux)
run: ./configure && make && make test -k
test-x86_64-osx:
runs-on: macos-15-intel
timeout-minutes: 2
steps:
- uses: actions/checkout@v4
- name: make & test tcc (x86_64-osx)
run: ./configure && make && make test -k
test-aarch64-osx:
runs-on: macos-15
timeout-minutes: 2
steps:
- uses: actions/checkout@v4
- name: make & test tcc (aarch64-osx)
run: ./configure && make && make test -k
test-x86_64-win32:
runs-on: windows-2025
timeout-minutes: 6
steps:
- uses: actions/checkout@v4
- name: build tcc (x86_64-win32)
shell: cmd
run: |
cd win32
for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" amd64
call build-tcc.bat -c cl -t x86_64
- name: test (x86_64-win32)
shell: cmd
run: |
cd tests
call test-win32.bat all -k
test-i386-win32:
runs-on: windows-2025
timeout-minutes: 6
steps:
- uses: actions/checkout@v4
- name: build tcc (i386-win32)
shell: cmd
run: |
cd win32
for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" x86
call build-tcc.bat -c cl -t i386
- name: test (i386-win32)
shell: cmd
run: |
cd tests
call test-win32.bat -p c:\mingw32\bin all -k
test-arm64-win32:
runs-on: windows-11-arm
timeout-minutes: 6
steps:
- uses: actions/checkout@v4
- name: build and test (arm64-win32)
shell: cmd
run: |
cd win32
for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64
call build-tcc.bat -c cl -t arm64
set "PATH=C:\Program Files\LLVM\bin;%CD%;%PATH%"
cd ..\tests
call test-win32.bat -c clang all -k
test-armv7-linux:
runs-on: ubuntu-22.04
timeout-minutes: 8
steps:
- uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v3
name: make & test tcc (armv7-linux)
with:
arch: armv7
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update -q -y
apt-get install -q -y gcc make
run: |
echo "::endgroup::" # flatten 'run container'
./configure && make && make test -k
test-aarch64-linux:
runs-on: ubuntu-22.04
timeout-minutes: 8
steps:
- uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v3
name: make & test tcc (aarch64-linux)
with:
arch: aarch64
distro: ubuntu24.04
githubToken: ${{ github.token }}
install: |
apt-get update -q -y
apt-get install -q -y gcc make
run: |
echo "::endgroup::" # flatten 'run container'
./configure && make && make test -k
test-riscv64-linux:
runs-on: ubuntu-22.04
timeout-minutes: 8
steps:
- uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v3
name: make & test tcc (riscv64-linux)
with:
arch: riscv64
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update -q -y
apt-get install -q -y gcc make
run: |
echo "::endgroup::" # flatten 'run container'
./configure && make && make test -k
test-riscv64-linux-native:
runs-on: ubuntu-24.04-riscv
timeout-minutes: 8
steps:
- uses: actions/checkout@v4
- name: make & test tcc (riscv64-linux native)
run: |
uname -m # riscv64
./configure && make && make test -k

70
.gitignore vendored Normal file
View File

@ -0,0 +1,70 @@
*~
\#*
.#*
*.o
*.a
*.exe
*.dll
*.obj
*.pdb
*.lib
*.exp
*.log
*.bz2
*.zip
.gdb_history
a.out
tcc_g
tcc
tcc_c
tcc_p
*-tcc
libtcc*.def
config*.h
*_.h
config*.mak
config.texi
conftest*
c2str
tags
TAGS
tcc.1
*.pod
*.tcov
tcc-doc.html
tcc-doc.info
win32/doc
win32/examples/libtcc_test.c
win32/libtcc
win32/lib/32
win32/lib/64
win32/include/float.h
win32/include/stdalign.h
win32/include/stdarg.h
win32/include/stdbool.h
win32/include/stddef.h
win32/include/stdnoreturn.h
win32/include/varargs.h
win32/include/tcclib.h
win32/include/tccdefs.h
win32/include/stdatomic.h
win32/include/tgmath.h
tests/tcctest[1234]
tests/tcctest.gcc
tests/*.out*
tests/*.ref
tests/*.txt
tests/*.gcc
tests/*-cc*
tests/*-tcc*
tests/libtcc_test
tests/libtcc_test_mt
tests/asm-c-connect
tests/asm-c-connect-sep
tests/vla_test
tests/hello
tests/tests2/fred.txt
libtcc.dylib

111
Changelog
View File

@ -1,3 +1,110 @@
version 0.9.28:
User interface:
- -b : bounds checker much improved (herman ten brugge)
- -bt : support for standalone backtraces also (grischka)
- -gdwarf : debug format (herman ten brugge)
- -M, -MM, and -MMD (Arthur Williams)
- -W[no-]error=<option> (Steffen Nurpmeso)
Platforms:
- new RISC-V (riscv64) target (Michael Matz)
- native macOS support for x86_64 (Michael Matz, Herman ten Brugge)
- arm and riscv64 assemblers (Danny Milosavljevic)
- Android support with position independent executables (grischka)
Features:
- _Static_assert() (matthias)
- __attribute__ ((cleanup(func))) (matthias)
- stdatomic (Dmitry Selyutin)
- asm goto ("jmp %l[label]" : : : : label) (Michael Matz)
Fixes:
- ... many, see git shortlog release_0_9_27...release_0_9_27
Version 0.9.27:
User interface:
- -x[c|a|n] filetype option (Sergey Korshunoff)
- -P[1], -dD, -dM preprocessor options (Sergey Korshunoff)
- -Wl,-(no-)whole-archive linker option (Reuben Thomas)
- -mms-bitfields option (David Mertens)
- -include <file> option (Michael Matz)
- -mno-sse on x86-64 disables use of SSE instructions
- @listfile support (Vlad Vissoultchev)
- tcc -ar/-impdef - formerly tiny_xxx tools integrated (grischka)
- CPATH, C_INCLUDE_PATH and LIBRARY_PATH environment variables support
(Andrew Aladjev, Urs Janssen)
Platforms:
- new AARCH64 (arm64) target (Edmund Grimley Evans)
- vastly improved support for ARM hard float calling convention
(Thomas Preud'homme, Daniel Glöckner)
- provide a runtime library for ARM (Thomas Preud'homme)
- many x86_64 ABI fixes incl. XMM register passing and tests (James Lyon)
- ABI tests with native compiler using libtcc (James Lyon)
- UNICODE startup code supports wmain and wWinMain (YX Hao)
- shared libraries for x86_64 (Michael Matz)
- Bootstrap native Windows 32/64 compiler using Cygwin+gcc (Christian Jullien)
Features:
- VLA (variable length array) improved (James Lyon, Pip Cet)
- import functions by ordinal in .def files on windows (YX Hao)
- x86/x86_64 assembler much improved (Michael Matz)
- simple dead code suppression (Edmund Grimley Evans, Michael Matz, grischka)
- implement round/fmin/fmax etc. math on windows (Avi Halachmi)
- #pragma once support (Sergey Korshunoff, Vlad Vissoultchev, ...)
- switch/case code improved (Zdenek Pavlas)
- ~15% faster by TinyAlloc fast memory allocator (Vlad Vissoultchev)
- standard conforming (and GCC compatible) struct initialization
(Michael Matz)
- bit-field layout made compatible with GCC (Michael Matz)
- UTF8 in string literals supported (Zdenek Pavlas)
_ _Generic(...) supported (Matthias Gatto)
Licensing:
- TinyCC partly relicensed to MIT license (See RELICENSING file).
version 0.9.26:
User interface:
- -MD/-MF (automatically generate dependencies for make)
- -pthread option (same as -D_REENTRANT -lpthread) (Henry Kroll III)
- -m32/-m64 to re-exec cross compiler (Henry Kroll III)
- -Wl, Mimic all GNU -option forms supported by ld (Kirill Smelkov)
- new LIBTCCAPI tcc_set_options() (grischka)
Platforms:
- Many improvements for x86-64 target (Shinichiro Hamaji, Michael Matz, grischka)
- x86-64 assembler (Frederic Feret)
- Many improvements for ARM target (Daniel Glöckner, Thomas Preud'homme)
- Support WinCE PE ARM (Timo VJ Lahde)
- Support ARM hardfloat calling convention (Thomas Preud'homme)
- Support SELinux (Security-Enhanced Linux) (Henry Kroll III)
- Support Debian GNU/kFreeBSD kernels (Pierre Chifflier)
- Support GNU/Hurd kernels (Thomas Preud'homme)
- Support OSX (tcc -run only) (Milutin Jovanovic)
- Support multiarch configuration (Thomas Preud'homme)
- Support out-of-tree build (Akim Demaille)
Features:
- C99 variable length arrays (Thomas Preud'homme & Joe Soroka)
- Asm labels for variables and functions (Thomas Preud'homme)
- STT_GNU_IFUNC (Indirect functions as externals) (Thomas Preud'homme)
- More tests (tests2) (Milutin Jovanovic)
version 0.9.25:
- first support for x86-64 target (Shinichiro Hamaji)
- support µClibc
- split tcc.c into tcc.h libtcc.c tccpp.c tccgen.c tcc.c
- improved preprocess output with linenumbers and spaces preserved
- tcc_relocate now copies code into user buffer
- fix bitfields with non-int types and in unions
- improve ARM cross-compiling (Daniel Glöckner)
- link stabstr sections from multiple objects
- better (still limited) support for multiple TCCStates
version 0.9.24:
- added verbosity levels -v, -vv, -vvv
@ -11,7 +118,7 @@ version 0.9.24:
- Import changesets (part 4) 428,457,460,467: defines for openbsd etc.
- Use _WIN32 for a windows hosted tcc and define it for the PE target,
otherwise define __unix / __linux (Detlef Riekenberg)
- Import changesets (part 3) 409,410: ARM EABI by Daniel Glöckner
- Import changesets (part 3) 409,410: ARM EABI by Daniel Glöckner
- Some in-between fixes:
TCC -E no longer hangs with macro calls involving newlines.
(next_nomacro1 now advances the read-pointer with TOK_LINEFEED)
@ -52,7 +159,7 @@ version 0.9.24:
432/434: Cast double and ptr to bool (grischka)
420: Zero pad x87 tenbyte long doubles (Felix Nawothnig)
417: Make 'sizeof' unsigned (Rob Landley)
397: Fix save_reg for longlongs (Daniel Glöckner)
397: Fix save_reg for longlongs (Daniel Glöckner)
396: Fix "invalid relocation entry" problem on ubuntu - (Bernhard Fischer)
- ignore AS_NEEDED ld command

71
CodingStyle Normal file
View File

@ -0,0 +1,71 @@
In general, use the same coding style as the surrounding code.
However, do not make any unnecessary changes as that complicates
the VCS (git) history and makes it harder to merge patches. So
do not modify code just to make it conform to a coding style.
Indentation
Turn on a "fill tabs with spaces" option in your editor.
Remove tabs and trailing spaces from any lines that are modified.
Note that some files are indented with 2 spaces (when they
have large indentation) while most are indented with 4 spaces.
Language
TCC is mostly implemented in C90. Do not use any non-C90 features
that are not already in use.
Non-C90 features currently in use, as revealed by
./configure --extra-cflags="-std=c90 -Wpedantic":
- long long (including "LL" constants)
- inline
- very long string constants
- assignment between function pointer and 'void *'
- "//" comments
- empty macro arguments (DEF_ASMTEST in i386-tok.h)
- unnamed struct and union fields (in struct Sym), a C11 feature
Testing
A simple "make test" is sufficient for some simple changes. However,
before committing a change consider performing some of the following
additional tests:
- Build and run "make test" on several architectures.
- Build with ./configure --enable-cross.
- If the generation of relocations has been changed, try compiling
with TCC and linking with GCC/Clang. If the linker has been
modified, try compiling with GCC/Clang and linking with TCC.
- Test with ASan/UBSan to detect memory corruption and undefined behaviour:
make clean
./configure
make
make test
cp libtcc.a libtcc.a.hide
make clean
./configure --extra-cflags="-fsanitize=address,undefined -g"
make
cp libtcc.a.hide libtcc.a
make test
- Test with Valgrind to detect some uses of uninitialised values:
make clean
./configure
make
# On Intel, because Valgrind does floating-point arithmetic differently:
( cd tests && gcc -I.. tcctest.c && valgrind -q ./a.out > test.ref )
make test TCC="valgrind -q --leak-check=full `pwd`/tcc -B`pwd` -I`pwd`"
(Because of how VLAs are implemented, invalid reads are expected
with 79_vla_continue.)

740
Makefile
View File

@ -1,313 +1,537 @@
# --------------------------------------------------------------------------
#
# Tiny C Compiler Makefile
#
include config.mak
CFLAGS+=-g -Wall
ifndef CONFIG_WIN32
LIBS=-lm
ifndef CONFIG_NOLDL
LIBS+=-ldl
endif
BCHECK_O=bcheck.o
endif
CFLAGS_P=$(CFLAGS) -pg -static -DCONFIG_TCC_STATIC
LIBS_P=
CFLAGS+=-mpreferred-stack-boundary=2
ifeq ($(GCC_MAJOR),2)
CFLAGS+=-m386 -malign-functions=0
else
CFLAGS+=-march=i386 -falign-functions=0 -fno-strict-aliasing
ifneq ($(GCC_MAJOR),3)
CFLAGS+=-Wno-pointer-sign -Wno-sign-compare
endif
ifndef TOP
TOP = .
INCLUDED = no
endif
DISAS=objdump -d
INSTALL=install
ifeq ($(findstring $(MAKECMDGOALS),clean distclean),)
include $(TOP)/config.mak
endif
ifeq (-$(GCC_MAJOR)-$(findstring $(GCC_MINOR),56789)-,-4--)
CFLAGS += -D_FORTIFY_SOURCE=0
endif
LIBTCC = libtcc.a
LIBTCC1 = libtcc1.a
LINK_LIBTCC =
LIBS =
CFLAGS += $(CPPFLAGS)
VPATH = $(TOPSRC)
-LTCC = $(TOP)/$(LIBTCC)
ifdef CONFIG_WIN32
PROGS=tcc$(EXESUF)
ifdef CONFIG_CROSS
PROGS+=c67-tcc$(EXESUF) arm-tcc$(EXESUF)
endif
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
CFG = -win
ifneq ($(CONFIG_static),yes)
LIBTCC = libtcc$(DLLSUF)
LIBTCCDEF = libtcc.def
endif
ifneq ($(CONFIG_debug),yes)
ifneq ($(CC_NAME),clang)
LDFLAGS += -s
endif
endif
NATIVE_TARGET = $(if $(findstring arm64,$(ARCH)),arm64-win32,$(ARCH)-win$(if $(findstring arm,$(ARCH)),ce,32))
else
ifeq ($(ARCH),i386)
PROGS=tcc$(EXESUF)
ifdef CONFIG_CROSS
PROGS+=arm-tcc$(EXESUF)
endif
endif
ifeq ($(ARCH),arm)
PROGS=tcc$(EXESUF)
ifdef CONFIG_CROSS
PROGS+=i386-tcc$(EXESUF)
endif
endif
ifdef CONFIG_CROSS
PROGS+=c67-tcc$(EXESUF) i386-win32-tcc$(EXESUF)
endif
CFG = -unx
LIBS+=-lm
ifneq ($(CONFIG_ldl),no)
LIBS+=-ldl
endif
ifneq ($(CONFIG_pthread),no)
LIBS+=-lpthread
endif
# make libtcc as static or dynamic library?
ifeq ($(CONFIG_static),no)
LIBTCC=libtcc$(DLLSUF)
export LD_LIBRARY_PATH := $(CURDIR)/$(TOP)
ifneq ($(CONFIG_rpath),no)
ifndef CONFIG_OSX
LINK_LIBTCC += -Wl,-rpath,"$(libdir)"
else
# macOS doesn't support env-vars libdir out of the box - which we need for
# `make test' when libtcc.dylib is used (configure --disable-static), so
# we bake a relative path into the binary. $libdir is used after install.
LINK_LIBTCC += -Wl,-rpath,"@executable_path/$(TOP)" -Wl,-rpath,"$(libdir)"
# -current/compatibility_version must not contain letters.
MACOS_DYLIB_VERSION := $(firstword $(subst rc, ,$(VERSION)))
DYLIBVER += -current_version $(MACOS_DYLIB_VERSION)
DYLIBVER += -compatibility_version $(MACOS_DYLIB_VERSION)
endif
endif
endif
NATIVE_TARGET = $(ARCH)
ifdef CONFIG_OSX
NATIVE_TARGET = $(ARCH)-osx
ifneq ($(CC_NAME),tcc)
LDFLAGS += -flat_namespace
ifneq (1,$(shell expr $(GCC_MAJOR) ">=" 15))
LDFLAGS += -undefined warning # depreciated in clang >= 15.0
endif
endif
export MACOSX_DEPLOYMENT_TARGET := 10.6
endif
endif
# run local version of tcc with local libraries and includes
TCC=./tcc -B. -I.
TCCFLAGS-unx = -B$(TOP) -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP)
TCCFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP) -L$(TOP)
TCCFLAGS = $(TCCFLAGS$(CFG))
TCC_LOCAL = $(TOP)/tcc$(EXESUF)
TCC = $(TCC_LOCAL) $(TCCFLAGS)
all: $(PROGS) \
libtcc1.a $(BCHECK_O) tcc-doc.html tcc.1 libtcc.a \
libtcc_test$(EXESUF)
# run tests with the installed tcc instead
ifdef TESTINSTALL
TCC_LOCAL = $(bindir)/tcc
TCCFLAGS-unx = -I$(TOP)
TCCFLAGS-win = -B$(bindir) -I$(TOP)
-LTCC = $(libdir)/$(LIBTCC) $(LINK_LIBTCC)
endif
Makefile: config.mak
CFLAGS_P = $(CFLAGS) -pg -static -DCONFIG_TCC_STATIC -DTCC_PROFILE
LIBS_P = $(LIBS)
LDFLAGS_P = $(LDFLAGS)
# auto test
DEF-i386 = -DTCC_TARGET_I386
DEF-i386-win32 = -DTCC_TARGET_I386 -DTCC_TARGET_PE
DEF-i386-OpenBSD = $(DEF-i386) -DTARGETOS_OpenBSD
DEF-x86_64 = -DTCC_TARGET_X86_64
DEF-x86_64-win32 = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE
DEF-x86_64-osx = -DTCC_TARGET_X86_64 -DTCC_TARGET_MACHO
DEF-arm-fpa = -DTCC_TARGET_ARM
DEF-arm-fpa-ld = -DTCC_TARGET_ARM -DLDOUBLE_SIZE=12
DEF-arm-vfp = -DTCC_TARGET_ARM -DTCC_ARM_VFP
DEF-arm-eabi = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI
DEF-arm-eabihf = $(DEF-arm-eabi) -DTCC_ARM_HARDFLOAT
DEF-arm = $(DEF-arm-eabihf)
DEF-arm-NetBSD = $(DEF-arm-eabihf) -DTARGETOS_NetBSD
DEF-arm-wince = $(DEF-arm-eabihf) -DTCC_TARGET_PE
DEF-arm64 = -DTCC_TARGET_ARM64
DEF-arm64-osx = $(DEF-arm64) -DTCC_TARGET_MACHO
DEF-arm64-FreeBSD = $(DEF-arm64) -DTARGETOS_FreeBSD
DEF-arm64-NetBSD = $(DEF-arm64) -DTARGETOS_NetBSD
DEF-arm64-OpenBSD = $(DEF-arm64) -DTARGETOS_OpenBSD
DEF-arm64-win32 = $(DEF-arm64) -DTCC_TARGET_PE
DEF-riscv64 = -DTCC_TARGET_RISCV64
DEF-c67 = -DTCC_TARGET_C67 -w # disable warnigs
DEF-x86_64-FreeBSD = $(DEF-x86_64) -DTARGETOS_FreeBSD
DEF-x86_64-NetBSD = $(DEF-x86_64) -DTARGETOS_NetBSD
DEF-x86_64-OpenBSD = $(DEF-x86_64) -DTARGETOS_OpenBSD
test: test.ref test.out
@if diff -u test.ref test.out ; then echo "Auto Test OK"; fi
ifeq ($(INCLUDED),no)
# --------------------------------------------------------------------------
# running top Makefile
tcctest.ref: tcctest.c
$(CC) $(CFLAGS) -w -I. -o $@ $<
PROGS = tcc$(EXESUF)
TCCLIBS = $(LIBTCCDEF) $(LIBTCC) $(LIBTCC1)
TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
test.ref: tcctest.ref
./tcctest.ref > $@
all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
test.out: tcc tcctest.c
$(TCC) -run tcctest.c > $@
# cross compiler targets to build
TCC_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm64-win32 arm-wince c67
TCC_X += riscv64 arm64-osx
# TCC_X += arm-fpa arm-fpa-ld arm-vfp arm-eabi
run: tcc tcctest.c
$(TCC) -run tcctest.c
# cross libtcc1.a targets to build
LIBTCC1_X = $(filter-out c67,$(TCC_X))
# iterated test2 (compile tcc then compile tcctest.c !)
test2: tcc tcc.c tcctest.c test.ref
$(TCC) -run tcc.c -B. -I. -run tcctest.c > test.out2
@if diff -u test.ref test.out2 ; then echo "Auto Test2 OK"; fi
PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF))
LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),$X-libtcc1.a)
# iterated test3 (compile tcc then compile tcc then compile tcctest.c !)
test3: tcc tcc.c tcctest.c test.ref
$(TCC) -run tcc.c -B. -I. -run tcc.c -B. -I. -run tcctest.c > test.out3
@if diff -u test.ref test.out3 ; then echo "Auto Test3 OK"; fi
# build cross compilers & libs
cross: $(LIBTCC1_CROSS) $(PROGS_CROSS)
# binary output test
test4: tcc test.ref
# dynamic output
$(TCC) -o tcctest1 tcctest.c
./tcctest1 > test1.out
@if diff -u test.ref test1.out ; then echo "Dynamic Auto Test OK"; fi
# static output
$(TCC) -static -o tcctest2 tcctest.c
./tcctest2 > test2.out
@if diff -u test.ref test2.out ; then echo "Static Auto Test OK"; fi
# object + link output
$(TCC) -c -o tcctest3.o tcctest.c
$(TCC) -o tcctest3 tcctest3.o
./tcctest3 > test3.out
@if diff -u test.ref test3.out ; then echo "Object Auto Test OK"; fi
# dynamic output + bound check
$(TCC) -b -o tcctest4 tcctest.c
./tcctest4 > test4.out
@if diff -u test.ref test4.out ; then echo "BCheck Auto Test OK"; fi
# build specific cross compiler & lib
cross-%: %-tcc$(EXESUF) %-libtcc1.a ;
# memory and bound check auto test
BOUNDS_OK = 1 4 8 10
BOUNDS_FAIL= 2 5 7 9 11 12 13
install: ; @$(MAKE) --no-print-directory install$(CFG)
install-strip: ; @$(MAKE) --no-print-directory install$(CFG) CONFIG_strip=yes
uninstall: ; @$(MAKE) --no-print-directory uninstall$(CFG)
btest: boundtest.c tcc
@for i in $(BOUNDS_OK); do \
if $(TCC) -b -run boundtest.c $$i ; then \
/bin/true ; \
else\
echo Failed positive test $$i ; exit 1 ; \
fi ;\
done ;\
for i in $(BOUNDS_FAIL); do \
if $(TCC) -b -run boundtest.c $$i ; then \
echo Failed negative test $$i ; exit 1 ;\
else\
/bin/true ; \
fi\
done ;\
echo Bound test OK
ifdef CONFIG_cross
all : cross
endif
# speed test
speed: tcc ex2 ex3
time ./ex2 1238 2 3 4 10 13 4
time ./tcc -I. ./ex2.c 1238 2 3 4 10 13 4
time ./ex3 35
time ./tcc -I. ./ex3.c 35
# --------------------------------------------
T = $(or $(CROSS_TARGET),$(NATIVE_TARGET))
X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
ex2: ex2.c
$(CC) $(CFLAGS) -o $@ $<
ifneq ($(T),$(NATIVE_TARGET))
$(if $(DEF-$T),,$(error error: unknown target: '$T'))
ifneq ($(CONFIG_WIN32),yes)
DEF-win = -DCONFIG_TCCDIR="\"$(tccdir)/win32\""
endif
# some default config for cross compilers
TRIPLET-i386 = i686-linux-gnu
TRIPLET-x86_64 = x86_64-linux-gnu
TRIPLET-arm = arm-linux-gnueabihf
TRIPLET-arm64 = aarch64-linux-gnu
TRIPLET-riscv64 = riscv64-linux-gnu
ifneq ($(TRIPLET-$T),)
# assume support files in "/usr/<triplet>"
ROOT-$T = /usr/$(TRIPLET-$T)
INC-$T = {B}/include:{R}/include
LIB-$T = {R}/lib:{B}
CRT-$T = {R}/lib
endif
DEFINES += $(DEF-$T)
DEFINES += $(if $(ROOT-$T),-DCONFIG_SYSROOT="\"$(ROOT-$T)\"")
DEFINES += $(if $(CRT-$T),-DCONFIG_TCC_CRTPREFIX="\"$(CRT-$T)\"")
DEFINES += $(if $(LIB-$T),-DCONFIG_TCC_LIBPATHS="\"$(LIB-$T)\"")
DEFINES += $(if $(INC-$T),-DCONFIG_TCC_SYSINCLUDEPATHS="\"$(INC-$T)\"")
DEFINES += $(if $(ELF-$T),-DCONFIG_TCC_ELFINTERP="\"$(ELF-$T)\"")
DEFINES += $(DEF-$(or $(findstring win,$T),unx))
DEFINES += -DCONFIG_TCC_CROSSPREFIX="\"$X\""
endif
ex3: ex3.c
$(CC) $(CFLAGS) -o $@ $<
# include custom configuration (see make help)
-include config-extra.mak
# so one can use: make EXTRA-DEFS=...
DEFINES += $(EXTRA-DEFS)
# find config.h with 'out of tree' builds
DEFINES += -I$(TOP)
CORE_FILES = tcc.c tcctools.c libtcc.c tccpp.c tccgen.c tccdbg.c tccelf.c tccasm.c tccrun.c
CORE_FILES += tcc.h config.h libtcc.h tcctok.h
i386_FILES = $(CORE_FILES) i386-gen.c i386-link.c i386-asm.c i386-asm.h i386-tok.h
i386-win32_FILES = $(i386_FILES) tccpe.c
x86_64_FILES = $(CORE_FILES) x86_64-gen.c x86_64-link.c i386-asm.c x86_64-asm.h
x86_64-win32_FILES = $(x86_64_FILES) tccpe.c
x86_64-osx_FILES = $(x86_64_FILES) tccmacho.c
arm_FILES = $(CORE_FILES) arm-gen.c arm-link.c arm-asm.c arm-tok.h
arm-wince_FILES = $(arm_FILES) tccpe.c
arm-fpa_FILES = $(arm_FILES)
arm-fpa-ld_FILES = $(arm_FILES)
arm-vfp_FILES = $(arm_FILES)
arm-eabi_FILES = $(arm_FILES)
arm-eabihf_FILES = $(arm_FILES)
arm64_FILES = $(CORE_FILES) arm64-gen.c arm64-link.c arm64-asm.c arm64-tok.h
arm64-osx_FILES = $(arm64_FILES) tccmacho.c
arm64-win32_FILES = $(arm64_FILES) tccpe.c
c67_FILES = $(CORE_FILES) c67-gen.c c67-link.c tcccoff.c
riscv64_FILES = $(CORE_FILES) riscv64-gen.c riscv64-link.c riscv64-asm.c
TCCDEFS_H$(subst yes,,$(CONFIG_predefs)) = tccdefs_.h
# libtcc sources
LIBTCC_SRC = $(filter-out tcc.c tcctools.c,$(filter %.c,$($T_FILES)))
ifeq ($(ONE_SOURCE),yes)
LIBTCC_OBJ = $(X)libtcc.o
LIBTCC_INC = $($T_FILES)
TCC_FILES = $(X)tcc.o
$(X)tcc.o $(X)libtcc.o : $(TCCDEFS_H)
else
LIBTCC_OBJ = $(patsubst %.c,$(X)%.o,$(LIBTCC_SRC))
LIBTCC_INC = $(filter %.h %-gen.c %-link.c,$($T_FILES))
TCC_FILES = $(X)tcc.o $(LIBTCC_OBJ)
$(X)tccpp.o : $(TCCDEFS_H)
$(X)libtcc.o : DEFINES += -DONE_SOURCE=0
$(CROSS_TARGET)-tcc.o : DEFINES += -DONE_SOURCE=0
endif
# native tcc always made from tcc.o and libtcc.[so|a]
tcc.o : DEFINES += -DONE_SOURCE=0
GITHASH:=$(shell git rev-parse --abbrev-ref HEAD 2>/dev/null || echo no)
ifneq ($(GITHASH),no)
GITHASH:=$(shell git log -1 --date=short --pretty='format:%cd $(GITHASH)@%h')
GITMODF:=$(shell git diff --quiet || echo '*')
DEF_GITHASH:= -DTCC_GITHASH="\"$(GITHASH)$(GITMODF)\""
endif
ifeq ($(CONFIG_debug),yes)
CFLAGS += -g
LDFLAGS += -g
endif
# convert "include/tccdefs.h" to "tccdefs_.h"
%_.h : include/%.h c2str.exe
$S./c2str.exe $< $@
c2str.exe : conftest.c
$S$(CC) -DC2STR $< -o $@
# target specific object rule
$(X)%.o : %.c $(LIBTCC_INC)
$S$(CC) -o $@ -c $< $(addsuffix ,$(DEFINES) $(CFLAGS))
# additional dependencies
$(X)tcc.o : tcctools.c
$(X)tcc.o : DEFINES += $(DEF_GITHASH)
# Host Tiny C Compiler
ifdef CONFIG_WIN32
tcc$(EXESUF): tcc.c i386-gen.c tccelf.c tccasm.c i386-asm.c tcctok.h libtcc.h i386-asm.h tccpe.c
$(CC) $(CFLAGS) -DTCC_TARGET_PE -o $@ $< $(LIBS)
else
ifeq ($(ARCH),i386)
tcc$(EXESUF): tcc.c i386-gen.c tccelf.c tccasm.c i386-asm.c tcctok.h libtcc.h i386-asm.h
$(CC) $(CFLAGS) -o $@ $< $(LIBS)
endif
ifeq ($(ARCH),arm)
tcc$(EXESUF): tcc.c arm-gen.c tccelf.c tccasm.c tcctok.h libtcc.h
$(CC) $(CFLAGS) -DTCC_TARGET_ARM -o $@ $< $(LIBS)
endif
endif
tcc$(EXESUF): tcc.o $(LIBTCC)
$S$(CC) -o $@ $^ $(addsuffix ,$(LIBS) $(LDFLAGS) $(LINK_LIBTCC))
# Cross Tiny C Compilers
i386-tcc$(EXESUF): tcc.c i386-gen.c tccelf.c tccasm.c i386-asm.c tcctok.h libtcc.h i386-asm.h
$(CC) $(CFLAGS) -o $@ $< $(LIBS)
# (the TCCDEFS_H dependency is only necessary for parallel makes,
# ala 'make -j x86_64-tcc i386-tcc tcc', which would create multiple
# c2str.exe and tccdefs_.h files in parallel, leading to access errors.
# This forces it to be made only once. Make normally tracks multiple paths
# to the same goals and only remakes it once, but that doesn't work over
# sub-makes like in this target)
%-tcc$(EXESUF): $(TCCDEFS_H) FORCE
@$(MAKE) --no-print-directory $@ CROSS_TARGET=$* ONE_SOURCE=$(or $(ONE_SOURCE),yes)
c67-tcc$(EXESUF): tcc.c c67-gen.c tccelf.c tccasm.c tcctok.h libtcc.h tcccoff.c
$(CC) $(CFLAGS) -DTCC_TARGET_C67 -o $@ $< $(LIBS)
arm-tcc$(EXESUF): tcc.c arm-gen.c tccelf.c tccasm.c tcctok.h libtcc.h
$(CC) $(CFLAGS) -DTCC_TARGET_ARM -DTCC_ARM_EABI -o $@ $< $(LIBS)
i386-win32-tcc$(EXESUF): tcc.c i386-gen.c tccelf.c tccasm.c i386-asm.c tcctok.h libtcc.h i386-asm.h tccpe.c
$(CC) $(CFLAGS) -DTCC_TARGET_PE -o $@ $< $(LIBS)
# windows utilities
tiny_impdef$(EXESUF): win32/tools/tiny_impdef.c
$(CC) $(CFLAGS) -o $@ $< -lkernel32
tiny_libmaker$(EXESUF): win32/tools/tiny_libmaker.c
$(CC) $(CFLAGS) -o $@ $< -lkernel32
# TinyCC runtime libraries
ifdef CONFIG_WIN32
# for windows, we must use TCC because we generate ELF objects
LIBTCC1_OBJS=$(addprefix win32/lib/, crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o) libtcc1.o
LIBTCC1_CC=./tcc.exe -Bwin32 -DTCC_TARGET_PE
else
LIBTCC1_OBJS=libtcc1.o
LIBTCC1_CC=$(CC)
endif
ifeq ($(ARCH),i386)
LIBTCC1_OBJS+=alloca86.o alloca86-bt.o
endif
%.o: %.c
$(LIBTCC1_CC) -O2 -Wall -c -o $@ $<
%.o: %.S
$(LIBTCC1_CC) -c -o $@ $<
libtcc1.a: $(LIBTCC1_OBJS)
$(AR) rcs $@ $^
bcheck.o: bcheck.c
$(CC) -O2 -Wall -c -o $@ $<
install: tcc_install libinstall
tcc_install: $(PROGS) tcc.1 libtcc1.a $(BCHECK_O) tcc-doc.html
mkdir -p "$(bindir)"
$(INSTALL) -s -m755 $(PROGS) "$(bindir)"
ifndef CONFIG_WIN32
mkdir -p "$(mandir)/man1"
$(INSTALL) tcc.1 "$(mandir)/man1"
endif
mkdir -p "$(tccdir)"
mkdir -p "$(tccdir)/include"
ifdef CONFIG_WIN32
mkdir -p "$(tccdir)/lib"
$(INSTALL) -m644 libtcc1.a win32/lib/*.def "$(tccdir)/lib"
cp -r win32/include/. "$(tccdir)/include"
cp -r win32/examples/. "$(tccdir)/examples"
else
$(INSTALL) -m644 libtcc1.a $(BCHECK_O) "$(tccdir)"
$(INSTALL) -m644 stdarg.h stddef.h stdbool.h float.h varargs.h \
tcclib.h "$(tccdir)/include"
endif
mkdir -p "$(docdir)"
$(INSTALL) -m644 tcc-doc.html "$(docdir)"
ifdef CONFIG_WIN32
$(INSTALL) -m644 win32/readme.txt "$(docdir)"
endif
clean:
rm -f *~ *.o *.a tcc tcct tcc_g tcctest.ref *.bin *.i ex2 \
core gmon.out test.out test.ref a.out tcc_p \
*.exe *.lib tcc.pod libtcc_test \
tcctest[1234] test[1234].out $(PROGS) win32/lib/*.o
distclean: clean
rm -f config.h config.mak config.texi
$(CROSS_TARGET)-tcc$(EXESUF): $(TCC_FILES)
$S$(CC) -o $@ $^ $(LIBS) $(LDFLAGS)
# profiling version
tcc_p: tcc.c Makefile
$(CC) $(CFLAGS_P) -o $@ $< $(LIBS_P)
tcc_p$(EXESUF): $($T_FILES)
$S$(CC) -o $@ $< $(DEFINES) $(CFLAGS_P) $(LIBS_P) $(LDFLAGS_P)
# libtcc generation and example
libinstall: libtcc.a
mkdir -p "$(libdir)"
$(INSTALL) -m644 libtcc.a "$(libdir)"
mkdir -p "$(includedir)"
$(INSTALL) -m644 libtcc.h "$(includedir)"
# static libtcc library
libtcc.a: $(LIBTCC_OBJ)
$S$(AR) rcs $@ $^
libtcc.o: tcc.c i386-gen.c Makefile
ifdef CONFIG_WIN32
$(CC) $(CFLAGS) -DTCC_TARGET_PE -DLIBTCC -c -o $@ $<
else
$(CC) $(CFLAGS) -DLIBTCC -c -o $@ $<
ifeq ($(CC_NAME)-$(ARCH),clang-x86_64)
# avoid 32-bit relocations in libtcc.a for its usage with tcc -run
libtcc.a: override CFLAGS += -fPIC
endif
libtcc.a: libtcc.o
$(AR) rcs $@ $^
# dynamic libtcc library
libtcc.so: $(LIBTCC_OBJ)
$S$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LIBS) $(LDFLAGS)
libtcc_test$(EXESUF): libtcc_test.c libtcc.a
$(CC) $(CFLAGS) -o $@ $< libtcc.a $(LIBS)
libtcc.so: override CFLAGS += -fPIC
libtcc.so: override LDFLAGS += -fPIC
libtest: libtcc_test
./libtcc_test
# OSX dynamic libtcc library
libtcc.dylib: $(LIBTCC_OBJ)
$S$(CC) -dynamiclib $(DYLIBVER) -install_name @rpath/$@ -o $@ $^ $(LDFLAGS)
# targets for development
# OSX libtcc.dylib (without rpath/ prefix)
libtcc.osx: $(LIBTCC_OBJ)
$S$(CC) -shared -install_name libtcc.dylib -o libtcc.dylib $^ $(LDFLAGS)
%.bin: %.c tcc
$(TCC) -g -o $@ $<
$(DISAS) $@
# windows dynamic libtcc library
libtcc.dll : $(LIBTCC_OBJ)
$S$(CC) -shared -o $@ $^ $(LDFLAGS)
libtcc.dll : DEFINES += -DLIBTCC_AS_DLL
instr: instr.o
objdump -d instr.o
# import file for windows libtcc.dll
libtcc.def : libtcc.dll tcc$(EXESUF)
$S$(XTCC) -impdef $< -o $@
XTCC ?= ./tcc$(EXESUF)
# tiny assembler testing
# TinyCC runtime libraries
libtcc1.a : tcc$(EXESUF) FORCE
@$(MAKE) -C lib
asmtest.ref: asmtest.S
$(CC) -c -o asmtest.ref.o asmtest.S
objdump -D asmtest.ref.o > $@
# Cross libtcc1.a
%-libtcc1.a : %-tcc$(EXESUF) FORCE
@$(MAKE) -C lib CROSS_TARGET=$*
# XXX: we compute tcc.c to go faster during development !
asmtest.out: asmtest.S tcc
# ./tcc tcc.c -c asmtest.S
#asmtest.out: asmtest.S tcc
./tcc -c asmtest.S
objdump -D asmtest.o > $@
.PRECIOUS: %-libtcc1.a
FORCE:
asmtest: asmtest.out asmtest.ref
@if diff -u --ignore-matching-lines="file format" asmtest.ref asmtest.out ; then echo "ASM Auto Test OK"; fi
# WHICH = which $1 2>/dev/null
# some versions of gnu-make do not recognize 'command' as a shell builtin
WHICH = sh -c 'command -v $1'
instr.o: instr.S
$(CC) -O2 -Wall -g -c -o $@ $<
cache: tcc_g
cachegrind ./tcc_g -o /tmp/linpack -lm bench/linpack.c
vg_annotate tcc.c > /tmp/linpack.cache.log
run-if = $(if $(shell $(call WHICH,$1x)),$S $1 $2,@true||echo "(skipping $@ - no $1)")
S = $(if $(findstring yes,$(SILENT)),@$(info * $@))
# --------------------------------------------------------------------------
# documentation and man page
tcc-doc.html: tcc-doc.texi
-texi2html -monolithic -number $<
$(call run-if,makeinfo,--no-split --html --number-sections -o $@ $<)
tcc.1: tcc-doc.texi
-./texi2pod.pl $< tcc.pod
-pod2man --section=1 --center=" " --release=" " tcc.pod > $@
tcc-doc.info: tcc-doc.texi
$(call run-if,makeinfo,$< || true)
FILE=tcc-$(shell cat VERSION)
tcc.1 : tcc-doc.pod
$(call run-if,pod2man,--section=1 --center="Tiny C Compiler" \
--release="$(VERSION)" $< >$@)
%.pod : %.texi
$(call run-if,perl,$(TOPSRC)/texi2pod.pl $< $@)
# tar release (use 'make -k tar' on a checkouted tree)
tar:
rm -rf /tmp/$(FILE)
cp -r . /tmp/$(FILE)
( cd /tmp ; tar zcvf ~/$(FILE).tar.gz $(FILE) --exclude CVS )
rm -rf /tmp/$(FILE)
doc : $(TCCDOCS)
# --------------------------------------------------------------------------
# install
INSTALL = install -m 644
INSTALLBIN = install -m 755 $(STRIP_$(CONFIG_strip))
STRIP_yes = -s
LIBTCC1_W = $(filter %-win32-libtcc1.a %-wince-libtcc1.a,$(LIBTCC1_CROSS))
LIBTCC1_U = $(filter-out $(LIBTCC1_W),$(wildcard *-libtcc1.a))
IB = $(if $1,$(IM) mkdir -p $2 && $(INSTALLBIN) $1 $2)
IBw = $(call IB,$(wildcard $1),$2)
IF = $(if $1,$(IM) mkdir -p $2 && $(INSTALL) $1 $2)
IFw = $(call IF,$(wildcard $1),$2)
IR = $(IM) mkdir -p $2 && cp -r $1/. $2
IM = @echo "-> $2 : $1" ;
BINCHECK = $(if $(wildcard $(PROGS) *-tcc$(EXESUF)),,@echo "Makefile: nothing found to install" && exit 1)
EXTRA_O = runmain.o bt-exe.o bt-dll.o bt-log.o bcheck.o
# install progs & libs
install-unx:
$(call BINCHECK)
$(call IBw,$(PROGS) *-tcc,"$(bindir)")
$(call IFw,$(LIBTCC1) $(EXTRA_O) $(LIBTCC1_U),"$(tccdir)")
$(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
$(call $(if $(findstring .so,$(LIBTCC)),IBw,IFw),$(LIBTCC),"$(libdir)")
$(call IF,$(TOPSRC)/libtcc.h,"$(includedir)")
$(call IFw,tcc.1,"$(mandir)/man1")
$(call IFw,tcc-doc.info,"$(infodir)")
$(call IFw,tcc-doc.html,"$(docdir)")
ifneq "$(wildcard $(LIBTCC1_W))" ""
$(call IFw,$(TOPSRC)/win32/lib/*.def $(LIBTCC1_W),"$(tccdir)/win32/lib")
$(call IR,$(TOPSRC)/win32/include,"$(tccdir)/win32/include")
$(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/win32/include")
endif
# uninstall
uninstall-unx:
@rm -fv $(addprefix "$(bindir)/",$(PROGS) $(PROGS_CROSS))
@rm -fv $(addprefix "$(libdir)/", libtcc*.a libtcc*.so libtcc.dylib)
@rm -fv $(addprefix "$(includedir)/", libtcc.h)
@rm -fv "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
@rm -fv "$(docdir)/tcc-doc.html"
@rm -frv "$(tccdir)"
# install progs & libs on windows
install-win:
$(call BINCHECK)
$(call IBw,$(PROGS) *-tcc.exe libtcc.dll,"$(bindir)")
$(call IF,$(TOPSRC)/win32/lib/*.def,"$(tccdir)/lib")
$(call IFw,libtcc1.a $(EXTRA_O) $(LIBTCC1_W),"$(tccdir)/lib")
$(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
$(call IR,$(TOPSRC)/win32/include,"$(tccdir)/include")
$(call IR,$(TOPSRC)/win32/examples,"$(tccdir)/examples")
$(call IF,$(TOPSRC)/tests/libtcc_test.c,"$(tccdir)/examples")
$(call IFw,$(TOPSRC)/libtcc.h libtcc.def libtcc.a,"$(libdir)")
$(call IFw,$(TOPSRC)/win32/tcc-win32.txt tcc-doc.html,"$(docdir)")
ifneq "$(wildcard $(LIBTCC1_U))" ""
$(call IFw,$(LIBTCC1_U),"$(tccdir)/lib")
$(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/lib/include")
endif
# uninstall on windows
uninstall-win:
@rm -fv $(foreach P,libtcc*.dll $(PROGS) *-tcc.exe,"$(bindir)"/$P)
@rm -fr $(foreach P,doc examples include lib libtcc,"$(tccdir)"/$P/*)
@rm -frv $(foreach P,doc examples include lib libtcc,"$(tccdir)"/$P)
# the msys-git shell works to configure && make except it does not have install
ifeq ($(OS),Windows_NT)
ifeq ($(shell $(call WHICH,install) || echo no),no)
INSTALL = cp
INSTALLBIN = cp
endif
endif
# --------------------------------------------------------------------------
# other stuff
TAGFILES = *.[ch] include/*.h lib/*.[chS]
tags : ; ctags $(TAGFILES)
# cannot have both tags and TAGS on windows
ETAGS : ; etags $(TAGFILES)
# create release tarball from *current* git branch (including tcc-doc.html
# and converting two files to CRLF)
TCC-VERSION = tcc-$(VERSION)
TCC-VERSION = tinycc-mob-$(shell git rev-parse --short=7 HEAD)
tar: tcc-doc.html
mkdir -p $(TCC-VERSION)
( cd $(TCC-VERSION) && git --git-dir ../.git checkout -f )
cp tcc-doc.html $(TCC-VERSION)
for f in tcc-win32.txt build-tcc.bat ; do \
cat win32/$$f | sed 's,\(.*\),\1\r,g' > $(TCC-VERSION)/win32/$$f ; \
done
tar cjf $(TCC-VERSION).tar.bz2 $(TCC-VERSION)
rm -rf $(TCC-VERSION)
git reset
config.mak:
$(if $(wildcard $@),,@echo "Please run ./configure." && exit 1)
# run all tests
test:
@$(MAKE) -C tests
# run test(s) from tests2 subdir (see make help)
tests2.%:
@$(MAKE) -C tests/tests2 $@
# run test(s) from testspp subdir (see make help)
testspp.%:
@$(MAKE) -C tests/pp $@
# run tests with code coverage
tcov-tes% : tcc_c$(EXESUF)
@rm -f $<.tcov
@$(MAKE) --no-print-directory TCC_LOCAL=$(CURDIR)/$< tes$*
tcc_c$(EXESUF): $($T_FILES)
$S$(TCC) tcc.c -o $@ -ftest-coverage $(DEFINES) $(LIBS)
# run tests with sanitize option
sani-tes% : tcc_s$(EXESUF)
@$(MAKE) --no-print-directory TCC_LOCAL=$(CURDIR)/$< tes$*
tcc_s$(EXESUF): $($T_FILES)
$S$(CC) tcc.c -o $@ -fsanitize=address,undefined $(DEFINES) $(CFLAGS) $(LDFLAGS) $(LIBS)
# test the installed tcc instead
test-install: $(TCCDEFS_H)
@$(MAKE) -C tests TESTINSTALL=yes #_all
clean:
@rm -f tcc *-tcc tcc_p tcc_c tcc_s
@rm -f tags ETAGS *.o *.a *.so* *.out *.log lib*.def *.exe *.dll
@rm -f a.out *.dylib *_.h *.pod *.tcov
@$(MAKE) -s -C lib $@
@$(MAKE) -s -C tests $@
distclean: clean
@rm -vf config.h config.mak config.texi
@rm -vf $(TCCDOCS)
.PHONY: all clean test tar tags ETAGS doc distclean install uninstall FORCE
help:
@echo "make"
@echo " build native compiler (from separate objects)"
@echo "make ONE_SOURCE=no/yes SILENT=no/yes"
@echo " force building from separate/one object(s), less/more silently"
@echo "make cross-TARGET"
@echo " build one specific cross compiler for 'TARGET'. Currently supported:"
@echo " $(wordlist 1,8,$(TCC_X))"
@echo " $(wordlist 9,99,$(TCC_X))"
@echo "make cross"
@echo " build all cross compilers"
@echo "make test"
@echo " run all tests"
@echo "make tests2.all / make tests2.37 / make tests2.37+"
@echo " run all/single test(s) from tests2, optionally update .expect"
@echo "make testspp.all / make testspp.17"
@echo " run all/single test(s) from tests/pp"
@echo "make tcov-test / tcov-tests2.37 / tcov-testspp.17"
@echo " run tests as above with code coverage. After test(s) see tcc_c$(EXESUF).tcov"
@echo "make sani-test / sani-tests2.37 / sani-testspp.17"
@echo " run tests as above with sanitize option."
@echo "make test-install"
@echo " run tests with the installed tcc"
@echo "Other supported make targets:"
@echo " install install-strip uninstall doc [dist]clean tags ETAGS tar help"
@echo "Custom configuration:"
@echo " The makefile includes a file 'config-extra.mak' if it is present."
@echo " This file may contain some custom configuration. For example to"
@echo " configure the search paths for a cross-compiler, assuming the"
@echo " support files in /usr/i686-linux-gnu:"
@echo " ROOT-i386 = /usr/i686-linux-gnu"
@echo " CRT-i386 = {R}/lib"
@echo " LIB-i386 = {B}:{R}/lib"
@echo " INC-i386 = {B}/include:{R}/include (*)"
@echo " DEF-i386 += -D__linux__"
@echo " Or also, for the cross platform files in /usr/<triplet>"
@echo " TRIPLET-i386 = i686-linux-gnu"
@echo " (*) tcc replaces {B} by 'tccdir' and {R} by 'CONFIG_SYSROOT'"
# --------------------------------------------------------------------------
endif # ($(INCLUDED),no)

28
README
View File

@ -7,19 +7,18 @@ Features:
- SMALL! You can compile and execute C code everywhere, for example on
rescue disks.
- FAST! tcc generates optimized x86 code. No byte code
overhead. Compile, assemble and link about 7 times faster than 'gcc
-O0'.
- FAST! tcc generates machine code for i386, x86_64, arm, aarch64 or
riscv64. Compiles and links about 10 times faster than 'gcc -O0'.
- UNLIMITED! Any C dynamic library can be used directly. TCC is
heading torward full ISOC99 compliance. TCC can of course compile
heading toward full ISOC99 compliance. TCC can of course compile
itself.
- SAFE! tcc includes an optional memory and bound checker. Bound
checked code can be mixed freely with standard code.
- Compile and execute C source directly. No linking or assembly
necessary. Full C preprocessor included.
necessary. Full C preprocessor included.
- C script supported : just add '#!/usr/local/bin/tcc -run' at the first
line of your C source, and execute it directly from the command
@ -28,15 +27,19 @@ Features:
Documentation:
-------------
1) Installation on a i386 Linux host (for Windows read win32/readme.txt)
1) Installation on Linux, BSD variants or macOS hosts:
./configure
make
make test
make install
By default, tcc is installed in /usr/local/bin.
./configure --help shows configuration options.
Notes: On BSD hosts, gmake should be used instead of make.
For Windows read tcc-win32.txt.
makeinfo must be installed to compile the doc. By default, tcc is
installed in /usr/local/bin. ./configure --help shows configuration
options.
2) Introduction
@ -65,7 +68,8 @@ operations given a list of numbers (benchmark).
ex3.c: compute fibonacci numbers (benchmark).
ex4.c: more complicated: X11 program. Very complicated test in fact
because standard headers are being used !
because standard headers are being used ! As for ex1.c, can also be launched
directly as a script: './ex4.c'.
ex5.c: 'hello world' with standard glibc headers.
@ -77,10 +81,8 @@ when doing 'make test'.
4) Full Documentation
Please read tcc-doc.html to have all the features of TCC.
Additional information is available for the Windows port in
win32/readme.txt.
Please read tcc-doc.html to have all the features of TCC. Additional
information for the Windows port is in tcc-win32.txt.
License:
-------

67
RELICENSING Normal file
View File

@ -0,0 +1,67 @@
Relicensing TinyCC
------------------
The authors listed below hereby confirm their agreement to relicense TinyCC
including their past contributions under the following terms:
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
Author (name) I agree (YES/NO) Files/Features (optional)
------------------------------------------------------------------------------
Adam Sampson YES makefiles
Daniel Glöckner NO arm-gen.c
Daniel Glöckner YES not arm-gen.c
Danny Milosavljevic YES arm-asm.c riscv64-asm.c
Edmund Grimley Evans YES arm64
Fabrice Bellard YES original author
Frédéric Féret YES x86 64/16 bit asm
grischka YES tccpe.c
Henry Kroll YES
Herman ten Brugge YES
Joe Soroka YES
Kirill Smelkov YES
mingodad YES
Pip Cet YES
Shinichiro Hamaji YES x86_64-gen.c
Steffen Nurpmeso YES
Vincent Lefèvre YES
Thomas Preud'homme YES arm-gen.c
Timo VJ Lähde (Timppa) ? tiny_libmaker.c
TK ? tcccoff.c c67-gen.c
Tyge Løvset YES tgmath.h, Windows tcc_libm.h math.h
Urs Janssen YES
waddlesplash YES
Christian Jullien YES Windows Cygwin build and tests
Reimar Döffinger YES
noneofyourbusiness YES
Cyan Ogilvie YES
------------------------------------------------------------------------------
Please add yourself to the list above (rsp. replace the question mark)
and (after fetching the latest version) commit to the "mob" branch with
commit message:
Relicensing TinyCC
Thanks.

53
TODO
View File

@ -1,18 +1,15 @@
TODO list:
Releases:
- release tcc on a regular basis
- testing repo.or.cz
Bugs:
- fix macro substitution with nested definitions (ShangHongzhang)
- i386 fastcall is mostly wrong
- FPU st(0) is left unclean (kwisatz haderach). Incompatible with
optimized gcc/msc code
- constructors
- cast bug (Peter Wang)
- define incomplete type if defined several times (Peter Wang).
- configure --cc=tcc (still one bug in libtcc1.c)
- test binutils/gcc compile
- tci patch + argument.
- see -lxxx bug (Michael Charity).
- see transparent union pb in /urs/include/sys/socket.h
- precise behaviour of typeof with arrays ? (__put_user macro)
but should suffice for most cases)
@ -21,19 +18,33 @@ Bugs:
- transform functions to function pointers in function parameters
(net/ipv4/ip_output.c)
- fix function pointer type display
- check lcc test suite -> fix bitfield binary operations
- check section alignment in C
- fix invalid cast in comparison 'if (v == (int8_t)v)'
- finish varargs.h support (gcc 3.2 testsuite issue)
- fix static functions declared inside block
- fix multiple unions init
- sizeof, alignof, typeof can still generate code in some cases.
- Fix the remaining libtcc memory leaks.
- make libtcc fully reentrant (except for the compilation stage itself).
- struct/union/enum definitions in nested scopes (see also Debian bug #770657)
- __STDC_IEC_559__: float f(void) { static float x = 0.0 / 0.0; return x; }
- memory may be leaked after errors (longjmp).
Portability:
- it is assumed that int is 32-bit and sizeof(int) == 4
- int is used when host or target size_t would make more sense
- TCC handles target floating-point (fp) values using the host's fp
arithmetic, which is simple and fast but may lead to exceptions
and inaccuracy and wrong representations when cross-compiling
Linking:
- static linking (-static) does sort of work
works with musl libc
glibc requires libc.so even when statically linked (very bad, but not
up to tcc)
Bound checking:
- '-b' bug.
- fix bound exit on RedHat 7.3
- setjmp is not supported properly in bound checking.
- fix bound check code with '&' on local variables (currently done
@ -45,13 +56,10 @@ Missing features:
- disable-asm and disable-bcheck options
- __builtin_expect()
- improve '-E' option.
- add '-MD' option
- atexit (Nigel Horne)
- packed attribute
- C99: add variable size arrays (gcc 3.2 testsuite issue)
- C99: add complex types (gcc 3.2 testsuite issue)
- postfix compound literals (see 20010124-1.c)
- interactive mode / integrated debugger
Optimizations:
@ -67,17 +75,17 @@ Not critical:
normative example - only relevant when using gotos! -> must add
boolean variable to tell if compound literal was already
initialized).
- add PowerPC or ARM code generator and improve codegen for RISC (need
- add PowerPC generator and improve codegen for RISC (need
to suppress VT_LOCAL and use a base register instead).
- interactive mode / integrated debugger
- fix preprocessor symbol redefinition
- better constant opt (&&, ||, ?:)
- add portable byte code generator and interpreter for other
unsupported architectures.
- C++: variable declaration in for, minimal 'class' support.
- win32: __intxx. use resolve for bchecked malloc et al.
check exception code (exception filter func).
- handle void (__attribute__() *ptr)()
- VLAs are implemented in a way that is not compatible with signals:
http://lists.gnu.org/archive/html/tinycc-devel/2015-11/msg00018.html
Fixed (probably):
@ -93,3 +101,8 @@ Fixed (probably):
- #include_next support for /usr/include/limits ?
- function pointers/lvalues in ? : (linux kernel net/core/dev.c)
- win32: add __stdcall, check GetModuleHandle for dlls.
- macro substitution with nested definitions (ShangHongzhang)
- with "-run" and libtcc, a PLT is now built.
- '-E' option was improved
- packed attribute is now supported
- ARM and ARM64 code generators have been added.

68
USES Normal file
View File

@ -0,0 +1,68 @@
The following software are known to use or support tcc builds.
Feel free to complete this list (*).
Name Short Description
---- -----------------
bigz An infinite precision Z & Q library.
gawk GNU awk.
gmp Library for arbitrary precision arithmetic.
gnumake GNU makefile.
gnu mes using tinycc to bootstrap a system
mpfr Multiple-precision floating-point library.
mpc Complex floating-point library with exact rounding.
mpv A free, open source, and cross-platform media player.
openlisp ISLISP ISO/IEC 13816 Lisp interpreter and compiler.
s-nail BSD Mail/POSIX mailx: send and receive Internet mail.
sqlite Embbedable SQL engine.
st Simple Terminal.
tcc Tiny CC which compiles itself.
zlib Lossless data-compression library.
(*) This list is ordered by name.
Forks & Experiments
-------------------
arm-thumb target
by Erlend Sveen <erlend.sveen@hotmail.com>
https://git.erlendjs.no/erlendjs/tinycc.git
riscv32 target
by Sam Ellicott <sellicott@cedarville.edu>
https://github.com/sellicott/tcc-riscv32.git
Transputer target
by David Smith <agentdavo@mac.com>
https://github.com/agentdavo/tinycc-transputer
tcc-65816 - Tiny C Compiler for 65816 CPU (based on V0.9.23) from SNES-SDK
https://github.com/nArnoSNES/tcc-65816
PE-UEFI arm64
by Andrei Warkentin <andrey.warkentin@gmail.com>
https://github.com/andreiw/tinycc/
TCCLS - global register allocator (proof of concept)
by Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
https://bitbucket.org/theStack/tccls_poc.git
softfloat
by Giovanni Mascellani <gio@debian.org>
https://gitlab.com/giomasce/tinycc.git
optimize 386
by Jason Hood <jadoxa@yahoo.com.au>
tcctcl : tcl binding
https://code.google.com/archive/p/tcltcc/
tcc4tcl : tcl binding
https://chiselapp.com/user/rkeene/repository/tcc4tcl/index
lua-tcc : allows a Lua script to compile C code
https://github.com/javierguerragiraldez/lua-tcc
tcclua : semi-high-level bindings for `libtcc`
https://github.com/nucular/tcclua/blob/master/tcc.lua

View File

@ -1 +1 @@
0.9.24
0.9.28rc

View File

@ -1,45 +0,0 @@
/* ---------------------------------------------- */
/* alloca86b.S */
#include "config.h"
.globl __bound__alloca
__bound__alloca:
pop %edx
pop %eax
mov %eax, %ecx
add $3,%eax
and $-4,%eax
jz p6
#ifdef TCC_TARGET_PE
p4:
cmp $4096,%eax
jle p5
sub $4096,%esp
sub $4096,%eax
test %eax,(%esp)
jmp p4
p5:
#endif
sub %eax,%esp
mov %esp,%eax
push %edx
push %eax
push %ecx
push %eax
call __bound_new_region
add $8, %esp
pop %eax
pop %edx
p6:
push %edx
push %edx
ret
/* ---------------------------------------------- */

View File

@ -1,33 +0,0 @@
/* ---------------------------------------------- */
/* alloca86.S */
#include "config.h"
.globl _alloca
_alloca:
pop %edx
pop %eax
add $3,%eax
and $-4,%eax
jz p3
#ifdef TCC_TARGET_PE
p1:
cmp $4096,%eax
jle p2
sub $4096,%esp
sub $4096,%eax
test %eax,(%esp)
jmp p1
p2:
#endif
sub %eax,%esp
mov %esp,%eax
p3:
push %edx
push %edx
ret
/* ---------------------------------------------- */

3092
arm-asm.c Normal file

File diff suppressed because it is too large Load Diff

1713
arm-gen.c

File diff suppressed because it is too large Load Diff

472
arm-link.c Normal file
View File

@ -0,0 +1,472 @@
#ifdef TARGET_DEFS_ONLY
#define EM_TCC_TARGET EM_ARM
/* relocation type for 32 bit data relocation */
#define R_DATA_32 R_ARM_ABS32
#define R_DATA_PTR R_ARM_ABS32
#define R_JMP_SLOT R_ARM_JUMP_SLOT
#define R_GLOB_DAT R_ARM_GLOB_DAT
#define R_COPY R_ARM_COPY
#define R_RELATIVE R_ARM_RELATIVE
#define R_NUM R_ARM_NUM
#define ELF_START_ADDR 0x00010000
#define ELF_PAGE_SIZE 0x10000
#define PCRELATIVE_DLLPLT 1
#define RELOCATE_DLLPLT 1
#else /* !TARGET_DEFS_ONLY */
#include "tcc.h"
#ifdef NEED_RELOC_TYPE
/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
relocations, returns -1. */
ST_FUNC int code_reloc (int reloc_type)
{
switch (reloc_type) {
case R_ARM_MOVT_ABS:
case R_ARM_MOVW_ABS_NC:
case R_ARM_THM_MOVT_ABS:
case R_ARM_THM_MOVW_ABS_NC:
case R_ARM_ABS32:
case R_ARM_REL32:
case R_ARM_GOTPC:
case R_ARM_GOTOFF:
case R_ARM_GOT32:
case R_ARM_GOT_PREL:
case R_ARM_COPY:
case R_ARM_GLOB_DAT:
case R_ARM_NONE:
case R_ARM_TARGET1:
case R_ARM_MOVT_PREL:
case R_ARM_MOVW_PREL_NC:
case R_ARM_TLS_LE32:
return 0;
case R_ARM_PC24:
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_PLT32:
case R_ARM_THM_PC22:
case R_ARM_THM_JUMP24:
case R_ARM_PREL31:
case R_ARM_V4BX:
case R_ARM_JUMP_SLOT:
return 1;
}
return -1;
}
/* Returns an enumerator to describe whether and when the relocation needs a
GOT and/or PLT entry to be created. See tcc.h for a description of the
different values. */
ST_FUNC int gotplt_entry_type (int reloc_type)
{
switch (reloc_type) {
case R_ARM_NONE:
case R_ARM_COPY:
case R_ARM_GLOB_DAT:
case R_ARM_JUMP_SLOT:
case R_ARM_TLS_LE32:
return NO_GOTPLT_ENTRY;
case R_ARM_PC24:
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_PLT32:
case R_ARM_THM_PC22:
case R_ARM_THM_JUMP24:
case R_ARM_MOVT_ABS:
case R_ARM_MOVW_ABS_NC:
case R_ARM_THM_MOVT_ABS:
case R_ARM_THM_MOVW_ABS_NC:
case R_ARM_PREL31:
case R_ARM_ABS32:
case R_ARM_REL32:
case R_ARM_V4BX:
case R_ARM_TARGET1:
case R_ARM_MOVT_PREL:
case R_ARM_MOVW_PREL_NC:
return AUTO_GOTPLT_ENTRY;
case R_ARM_GOTPC:
case R_ARM_GOTOFF:
return BUILD_GOT_ONLY;
case R_ARM_GOT32:
case R_ARM_GOT_PREL:
return ALWAYS_GOTPLT_ENTRY;
}
return -1;
}
#ifdef NEED_BUILD_GOT
ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
{
Section *plt = s1->plt;
uint8_t *p;
unsigned plt_offset;
/* when building a DLL, GOT entry accesses must be done relative to
start of GOT (see x86_64 example above) */
/* empty PLT: create PLT0 entry that push address of call site and
jump to ld.so resolution routine (GOT + 8) */
if (plt->data_offset == 0) {
p = section_ptr_add(plt, 20);
write32le(p, 0xe52de004); /* push {lr} */
write32le(p+4, 0xe59fe004); /* ldr lr, [pc, #4] */
write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */
write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
/* p+16 is set in relocate_plt */
}
plt_offset = plt->data_offset;
if (attr->plt_thumb_stub) {
p = section_ptr_add(plt, 4);
write32le(p, 0x4778); /* bx pc */
write32le(p+2, 0x46c0); /* nop */
}
p = section_ptr_add(plt, 16);
/* save GOT offset for relocate_plt */
write32le(p + 4, got_offset);
return plt_offset;
}
/* relocate the PLT: compute addresses and offsets in the PLT now that final
address for PLT and GOT are known (see fill_program_header) */
ST_FUNC void relocate_plt(TCCState *s1)
{
uint8_t *p, *p_end;
if (!s1->plt)
return;
p = s1->plt->data;
p_end = p + s1->plt->data_offset;
if (p < p_end) {
int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
write32le(s1->plt->data + 16, x - 4);
p += 20;
while (p < p_end) {
unsigned off = x + read32le(p + 4) + (s1->plt->data - p) + 4;
if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
p += 4;
write32le(p, 0xe28fc200 | ((off >> 28) & 0xf)); // add ip, pc, #0xN0000000
write32le(p + 4, 0xe28cc600 | ((off >> 20) & 0xff)); // add ip, pc, #0xNN00000
write32le(p + 8, 0xe28cca00 | ((off >> 12) & 0xff)); // add ip, ip, #0xNN000
write32le(p + 12, 0xe5bcf000 | (off & 0xfff)); // ldr pc, [ip, #0xNNN]!
p += 16;
}
}
if (s1->plt->reloc) {
ElfW_Rel *rel;
p = s1->got->data;
for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {
write32le(p + rel->r_offset, s1->plt->sh_addr);
}
}
}
#endif
#endif
ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
{
ElfW(Sym) *sym;
int sym_index, esym_index;
sym_index = ELFW(R_SYM)(rel->r_info);
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
switch(type) {
case R_ARM_PC24:
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_PLT32:
{
int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;
unsigned code = read32le(ptr);
x = code & 0x00ffffff;
#ifdef DEBUG_RELOC
printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);
#endif
code &= 0xff000000;
x <<= 2;
if (x & 0x2000000)
x -= 0x4000000;
blx_avail = (CONFIG_TCC_CPUVER >= 5);
is_thumb = val & 1;
is_bl = code == 0xeb000000;
is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl));
x += val - addr;
#ifdef DEBUG_RELOC
printf (" newx=0x%x name=%s\n", x,
(char *) symtab_section->link->data + sym->st_name);
#endif
h = x & 2;
th_ko = (x & 3) && (!blx_avail || !is_call);
if (th_ko || x >= 0x2000000 || x < -0x2000000)
tcc_error_noabort("can't relocate value at %x,%d",addr, type);
x >>= 2;
x &= 0xffffff;
/* Only reached if blx is avail and it is a call */
if (is_thumb) {
x |= h << 24;
code = 0xfa000000; /* bl -> blx */
}
write32le(ptr, code | x);
}
return;
/* Since these relocations only concern Thumb-2 and blx instruction was
introduced before Thumb-2, we can assume blx is available and not
guard its use */
case R_ARM_THM_PC22:
case R_ARM_THM_JUMP24:
{
int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11;
int to_thumb, is_call, to_plt, blx_bit = 1 << 12;
Section *plt;
/* weak reference */
if (sym->st_shndx == SHN_UNDEF &&
ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
return;
/* Get initial offset */
hi = read16le(ptr);
lo = read16le(ptr+2);
s = (hi >> 10) & 1;
j1 = (lo >> 13) & 1;
j2 = (lo >> 11) & 1;
i1 = (j1 ^ s) ^ 1;
i2 = (j2 ^ s) ^ 1;
imm10 = hi & 0x3ff;
imm11 = lo & 0x7ff;
x = (s << 24) | (i1 << 23) | (i2 << 22) |
(imm10 << 12) | (imm11 << 1);
if (x & 0x01000000)
x -= 0x02000000;
/* Relocation infos */
to_thumb = val & 1;
plt = s1->plt;
to_plt = (val >= plt->sh_addr) &&
(val < plt->sh_addr + plt->data_offset);
is_call = (type == R_ARM_THM_PC22);
if (!to_thumb && !to_plt && !is_call) {
int index;
uint8_t *p;
char *name, buf[1024];
Section *text;
name = (char *) symtab_section->link->data + sym->st_name;
text = s1->sections[sym->st_shndx];
/* Modify reloc to target a thumb stub to switch to ARM */
snprintf(buf, sizeof(buf), "%s_from_thumb", name);
index = put_elf_sym(symtab_section,
text->data_offset + 1,
sym->st_size, sym->st_info, 0,
sym->st_shndx, buf);
to_thumb = 1;
val = text->data_offset + 1;
rel->r_info = ELFW(R_INFO)(index, type);
/* Create a thumb stub function to switch to ARM mode */
put_elf_reloc(symtab_section, text,
text->data_offset + 4, R_ARM_JUMP24,
sym_index);
p = section_ptr_add(text, 8);
write32le(p, 0x4778); /* bx pc */
write32le(p+2, 0x46c0); /* nop */
write32le(p+4, 0xeafffffe); /* b $sym */
}
/* Compute final offset */
x += val - addr;
if (!to_thumb && is_call) {
blx_bit = 0; /* bl -> blx */
x = (x + 3) & -4; /* Compute offset from aligned PC */
}
/* Check that relocation is possible
* offset must not be out of range
* if target is to be entered in arm mode:
- bit 1 must not set
- instruction must be a call (bl) or a jump to PLT */
if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
if (to_thumb || (val & 2) || (!is_call && !to_plt))
tcc_error_noabort("can't relocate value at %x,%d",addr, type);
/* Compute and store final offset */
s = (x >> 24) & 1;
i1 = (x >> 23) & 1;
i2 = (x >> 22) & 1;
j1 = s ^ (i1 ^ 1);
j2 = s ^ (i2 ^ 1);
imm10 = (x >> 12) & 0x3ff;
imm11 = (x >> 1) & 0x7ff;
write16le(ptr, (hi & 0xf800) |
(s << 10) | imm10);
write16le(ptr+2, (lo & 0xc000) |
(j1 << 13) | blx_bit | (j2 << 11) |
imm11);
}
return;
case R_ARM_MOVT_ABS:
case R_ARM_MOVW_ABS_NC:
{
int x, imm4, imm12;
if (type == R_ARM_MOVT_ABS)
val >>= 16;
imm12 = val & 0xfff;
imm4 = (val >> 12) & 0xf;
x = (imm4 << 16) | imm12;
if (type == R_ARM_THM_MOVT_ABS)
write32le(ptr, read32le(ptr) | x);
else
add32le(ptr, x);
}
return;
case R_ARM_MOVT_PREL:
case R_ARM_MOVW_PREL_NC:
{
int insn = read32le(ptr);
int addend = ((insn >> 4) & 0xf000) | (insn & 0xfff);
addend = (addend ^ 0x8000) - 0x8000;
val += addend - addr;
if (type == R_ARM_MOVT_PREL)
val >>= 16;
write32le(ptr, (insn & 0xfff0f000) |
((val & 0xf000) << 4) | (val & 0xfff));
}
return;
case R_ARM_THM_MOVT_ABS:
case R_ARM_THM_MOVW_ABS_NC:
{
int x, i, imm4, imm3, imm8;
if (type == R_ARM_THM_MOVT_ABS)
val >>= 16;
imm8 = val & 0xff;
imm3 = (val >> 8) & 0x7;
i = (val >> 11) & 1;
imm4 = (val >> 12) & 0xf;
x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4;
if (type == R_ARM_THM_MOVT_ABS)
write32le(ptr, read32le(ptr) | x);
else
add32le(ptr, x);
}
return;
case R_ARM_PREL31:
{
int x;
x = read32le(ptr) & 0x7fffffff;
write32le(ptr, read32le(ptr) & 0x80000000);
x = (x * 2) / 2;
x += val - addr;
if((x^(x>>1))&0x40000000)
tcc_error_noabort("can't relocate value at %x,%d",addr, type);
write32le(ptr, read32le(ptr) | (x & 0x7fffffff));
}
return;
case R_ARM_ABS32:
case R_ARM_TARGET1:
if (s1->output_type & TCC_OUTPUT_DYN) {
esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
qrel->r_offset = rel->r_offset;
if (esym_index) {
qrel->r_info = ELFW(R_INFO)(esym_index, R_ARM_ABS32);
qrel++;
return;
} else {
qrel->r_info = ELFW(R_INFO)(0, R_ARM_RELATIVE);
qrel++;
}
}
add32le(ptr, val);
return;
case R_ARM_REL32:
add32le(ptr, val - addr);
return;
case R_ARM_GOTPC:
add32le(ptr, s1->got->sh_addr - addr);
return;
case R_ARM_GOTOFF:
add32le(ptr, val - s1->got->sh_addr);
return;
case R_ARM_GOT32:
/* we load the got offset */
add32le(ptr, get_sym_attr(s1, sym_index, 0)->got_offset);
return;
case R_ARM_GOT_PREL:
/* we load the pc relative got offset */
add32le(ptr, s1->got->sh_addr +
get_sym_attr(s1, sym_index, 0)->got_offset -
addr);
return;
case R_ARM_COPY:
return;
case R_ARM_V4BX:
/* trade Thumb support for ARMv4 support */
if ((0x0ffffff0 & read32le(ptr)) == 0x012FFF10)
write32le(ptr, read32le(ptr) ^ 0xE12FFF10 ^ 0xE1A0F000); /* BX Rm -> MOV PC, Rm */
return;
case R_ARM_GLOB_DAT:
case R_ARM_JUMP_SLOT:
write32le(ptr, val);
return;
case R_ARM_NONE:
/* Nothing to do. Normally used to indicate a dependency
on a certain symbol (like for exception handling under EABI). */
return;
case R_ARM_RELATIVE:
#ifdef TCC_TARGET_PE
add32le(ptr, val - s1->pe_imagebase);
#endif
/* do nothing */
return;
case R_ARM_TLS_LE32:
{
ElfW(Sym) *sym;
Section *sec;
int32_t x;
addr_t tls_start = 0, tls_end = 0, tls_align = 1;
int i;
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
sec = s1->sections[sym->st_shndx];
for (i = 1; i < s1->nb_sections; i++) {
Section *s = s1->sections[i];
if (s->sh_flags & SHF_TLS && s->sh_size) {
if (!tls_start || s->sh_addr < tls_start)
tls_start = s->sh_addr;
if (s->sh_addr + s->sh_size > tls_end)
tls_end = s->sh_addr + s->sh_size;
if (s->sh_addralign > tls_align)
tls_align = s->sh_addralign;
}
}
if (tls_end > tls_start) {
x = val - tls_start + 8;
} else {
x = val - sec->sh_addr - sec->data_offset + 8;
}
add32le(ptr, x);
}
return;
default:
fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n",
type, (unsigned)addr, ptr, (unsigned)val);
return;
}
}
#endif /* !TARGET_DEFS_ONLY */

406
arm-tok.h Normal file
View File

@ -0,0 +1,406 @@
/* ------------------------------------------------------------------ */
/* WARNING: relative order of tokens is important. */
/* register */
DEF_ASM(r0)
DEF_ASM(r1)
DEF_ASM(r2)
DEF_ASM(r3)
DEF_ASM(r4)
DEF_ASM(r5)
DEF_ASM(r6)
DEF_ASM(r7)
DEF_ASM(r8)
DEF_ASM(r9)
DEF_ASM(r10)
DEF_ASM(r11) /* fp */
DEF_ASM(r12) /* ip[c] */
DEF_ASM(r13) /* sp */
DEF_ASM(r14) /* lr */
DEF_ASM(r15) /* pc */
/* synonym register names */
DEF_ASM(a1) /* argument/result/scratch register 1: alias for r0 */
DEF_ASM(a2) /* argument/result/scratch register 2: alias for r1 */
DEF_ASM(a3) /* argument/result/scratch register 3: alias for r2 */
DEF_ASM(a4) /* argument/result/scratch register 4: alias for r3 */
DEF_ASM(v1) /* variable register 1: alias for r4 */
DEF_ASM(v2) /* variable register 2: alias for r5 */
DEF_ASM(v3) /* variable register 3: alias for r6 */
DEF_ASM(v4) /* variable register 4: alias for r7 */
DEF_ASM(v5) /* ARM state variable register 5: alias for r8 */
DEF_ASM(v6) /* ARM state variable register 6: alias for r9 */
DEF_ASM(v7) /* ARM state variable register 7: alias for r10 */
DEF_ASM(v8) /* ARM state variable register 8: alias for r11 */
/* special register names */
DEF_ASM(sb) /* alias for r9 */
DEF_ASM(sl) /* alias for r10 */
DEF_ASM(fp) /* alias for r11 */
DEF_ASM(ip) /* alias for r12 */
DEF_ASM(sp) /* alias for r13 */
DEF_ASM(lr) /* alias for r14 */
DEF_ASM(pc) /* alias for r15 */
/* coprocessors */
DEF_ASM(p0)
DEF_ASM(p1)
DEF_ASM(p2)
DEF_ASM(p3)
DEF_ASM(p4)
DEF_ASM(p5)
DEF_ASM(p6)
DEF_ASM(p7)
DEF_ASM(p8)
DEF_ASM(p9)
DEF_ASM(p10)
DEF_ASM(p11)
DEF_ASM(p12)
DEF_ASM(p13)
DEF_ASM(p14)
DEF_ASM(p15)
/* coprocessor registers */
DEF_ASM(c0)
DEF_ASM(c1)
DEF_ASM(c2)
DEF_ASM(c3)
DEF_ASM(c4)
DEF_ASM(c5)
DEF_ASM(c6)
DEF_ASM(c7)
DEF_ASM(c8)
DEF_ASM(c9)
DEF_ASM(c10)
DEF_ASM(c11)
DEF_ASM(c12)
DEF_ASM(c13)
DEF_ASM(c14)
DEF_ASM(c15)
/* single-precision VFP registers */
DEF_ASM(s0)
DEF_ASM(s1)
DEF_ASM(s2)
DEF_ASM(s3)
DEF_ASM(s4)
DEF_ASM(s5)
DEF_ASM(s6)
DEF_ASM(s7)
DEF_ASM(s8)
DEF_ASM(s9)
DEF_ASM(s10)
DEF_ASM(s11)
DEF_ASM(s12)
DEF_ASM(s13)
DEF_ASM(s14)
DEF_ASM(s15)
DEF_ASM(s16)
DEF_ASM(s17)
DEF_ASM(s18)
DEF_ASM(s19)
DEF_ASM(s20)
DEF_ASM(s21)
DEF_ASM(s22)
DEF_ASM(s23)
DEF_ASM(s24)
DEF_ASM(s25)
DEF_ASM(s26)
DEF_ASM(s27)
DEF_ASM(s28)
DEF_ASM(s29)
DEF_ASM(s30)
DEF_ASM(s31)
/* double-precision VFP registers */
DEF_ASM(d0)
DEF_ASM(d1)
DEF_ASM(d2)
DEF_ASM(d3)
DEF_ASM(d4)
DEF_ASM(d5)
DEF_ASM(d6)
DEF_ASM(d7)
DEF_ASM(d8)
DEF_ASM(d9)
DEF_ASM(d10)
DEF_ASM(d11)
DEF_ASM(d12)
DEF_ASM(d13)
DEF_ASM(d14)
DEF_ASM(d15)
/* VFP status registers */
DEF_ASM(fpsid)
DEF_ASM(fpscr)
DEF_ASM(fpexc)
/* VFP magical ARM register */
DEF_ASM(apsr_nzcv)
/* data processing directives */
DEF_ASM(asl)
/* instructions that have no condition code */
DEF_ASM(cdp2)
DEF_ASM(ldc2)
DEF_ASM(ldc2l)
DEF_ASM(stc2)
DEF_ASM(stc2l)
#define ARM_INSTRUCTION_GROUP(tok) ((((tok) - TOK_ASM_nopeq) & 0xFFFFFFF0) + TOK_ASM_nopeq)
/* Note: condition code is 4 bits */
#define DEF_ASM_CONDED(x) \
DEF(TOK_ASM_ ## x ## eq, #x "eq") \
DEF(TOK_ASM_ ## x ## ne, #x "ne") \
DEF(TOK_ASM_ ## x ## cs, #x "cs") \
DEF(TOK_ASM_ ## x ## cc, #x "cc") \
DEF(TOK_ASM_ ## x ## mi, #x "mi") \
DEF(TOK_ASM_ ## x ## pl, #x "pl") \
DEF(TOK_ASM_ ## x ## vs, #x "vs") \
DEF(TOK_ASM_ ## x ## vc, #x "vc") \
DEF(TOK_ASM_ ## x ## hi, #x "hi") \
DEF(TOK_ASM_ ## x ## ls, #x "ls") \
DEF(TOK_ASM_ ## x ## ge, #x "ge") \
DEF(TOK_ASM_ ## x ## lt, #x "lt") \
DEF(TOK_ASM_ ## x ## gt, #x "gt") \
DEF(TOK_ASM_ ## x ## le, #x "le") \
DEF(TOK_ASM_ ## x, #x) \
DEF(TOK_ASM_ ## x ## rsvd, #x "rsvd")
/* Note: condition code is 4 bits */
#define DEF_ASM_CONDED_WITH_SUFFIX(x, y) \
DEF(TOK_ASM_ ## x ## eq ## _ ## y, #x "eq." #y) \
DEF(TOK_ASM_ ## x ## ne ## _ ## y, #x "ne." #y) \
DEF(TOK_ASM_ ## x ## cs ## _ ## y, #x "cs." #y) \
DEF(TOK_ASM_ ## x ## cc ## _ ## y, #x "cc." #y) \
DEF(TOK_ASM_ ## x ## mi ## _ ## y, #x "mi." #y) \
DEF(TOK_ASM_ ## x ## pl ## _ ## y, #x "pl." #y) \
DEF(TOK_ASM_ ## x ## vs ## _ ## y, #x "vs." #y) \
DEF(TOK_ASM_ ## x ## vc ## _ ## y, #x "vc." #y) \
DEF(TOK_ASM_ ## x ## hi ## _ ## y, #x "hi." #y) \
DEF(TOK_ASM_ ## x ## ls ## _ ## y, #x "ls." #y) \
DEF(TOK_ASM_ ## x ## ge ## _ ## y, #x "ge." #y) \
DEF(TOK_ASM_ ## x ## lt ## _ ## y, #x "lt." #y) \
DEF(TOK_ASM_ ## x ## gt ## _ ## y, #x "gt." #y) \
DEF(TOK_ASM_ ## x ## le ## _ ## y, #x "le." #y) \
DEF(TOK_ASM_ ## x ## _ ## y, #x "." #y) \
DEF(TOK_ASM_ ## x ## rsvd ## _ ## y, #x "rsvd." #y)
#define DEF_ASM_CONDED_VFP_F32_F64(x) \
DEF_ASM_CONDED_WITH_SUFFIX(x, f32) \
DEF_ASM_CONDED_WITH_SUFFIX(x, f64)
#define DEF_ASM_CONDED_WITH_TWO_SUFFIXES(x, y, z) \
DEF(TOK_ASM_ ## x ## eq ## _ ## y ## _ ## z, #x "eq." #y "." #z) \
DEF(TOK_ASM_ ## x ## ne ## _ ## y ## _ ## z, #x "ne." #y "." #z) \
DEF(TOK_ASM_ ## x ## cs ## _ ## y ## _ ## z, #x "cs." #y "." #z) \
DEF(TOK_ASM_ ## x ## cc ## _ ## y ## _ ## z, #x "cc." #y "." #z) \
DEF(TOK_ASM_ ## x ## mi ## _ ## y ## _ ## z, #x "mi." #y "." #z) \
DEF(TOK_ASM_ ## x ## pl ## _ ## y ## _ ## z, #x "pl." #y "." #z) \
DEF(TOK_ASM_ ## x ## vs ## _ ## y ## _ ## z, #x "vs." #y "." #z) \
DEF(TOK_ASM_ ## x ## vc ## _ ## y ## _ ## z, #x "vc." #y "." #z) \
DEF(TOK_ASM_ ## x ## hi ## _ ## y ## _ ## z, #x "hi." #y "." #z) \
DEF(TOK_ASM_ ## x ## ls ## _ ## y ## _ ## z, #x "ls." #y "." #z) \
DEF(TOK_ASM_ ## x ## ge ## _ ## y ## _ ## z, #x "ge." #y "." #z) \
DEF(TOK_ASM_ ## x ## lt ## _ ## y ## _ ## z, #x "lt." #y "." #z) \
DEF(TOK_ASM_ ## x ## gt ## _ ## y ## _ ## z, #x "gt." #y "." #z) \
DEF(TOK_ASM_ ## x ## le ## _ ## y ## _ ## z, #x "le." #y "." #z) \
DEF(TOK_ASM_ ## x ## _ ## y ## _ ## z, #x "." #y "." #z) \
DEF(TOK_ASM_ ## x ## rsvd ## _ ## y ## _ ## z, #x "rsvd." #y "." #z)
/* Note: add new tokens after nop (MUST always use DEF_ASM_CONDED) */
DEF_ASM_CONDED(nop)
DEF_ASM_CONDED(wfe)
DEF_ASM_CONDED(wfi)
DEF_ASM_CONDED(swi)
DEF_ASM_CONDED(svc)
/* misc */
DEF_ASM_CONDED(clz)
/* size conversion */
DEF_ASM_CONDED(sxtb)
DEF_ASM_CONDED(sxth)
DEF_ASM_CONDED(uxtb)
DEF_ASM_CONDED(uxth)
DEF_ASM_CONDED(movt)
DEF_ASM_CONDED(movw)
/* multiplication */
DEF_ASM_CONDED(mul)
DEF_ASM_CONDED(muls)
DEF_ASM_CONDED(mla)
DEF_ASM_CONDED(mlas)
DEF_ASM_CONDED(smull)
DEF_ASM_CONDED(smulls)
DEF_ASM_CONDED(umull)
DEF_ASM_CONDED(umulls)
DEF_ASM_CONDED(smlal)
DEF_ASM_CONDED(smlals)
DEF_ASM_CONDED(umlal)
DEF_ASM_CONDED(umlals)
DEF_ASM_CONDED(mls)
DEF_ASM_CONDED(udiv)
DEF_ASM_CONDED(sdiv)
/* load/store */
DEF_ASM_CONDED(ldr)
DEF_ASM_CONDED(ldrb)
DEF_ASM_CONDED(str)
DEF_ASM_CONDED(strb)
DEF_ASM_CONDED(ldrex)
DEF_ASM_CONDED(ldrexb)
DEF_ASM_CONDED(ldrexh)
DEF_ASM_CONDED(strex)
DEF_ASM_CONDED(strexb)
DEF_ASM_CONDED(strexh)
DEF_ASM_CONDED(ldrh)
DEF_ASM_CONDED(ldrsh)
DEF_ASM_CONDED(ldrsb)
DEF_ASM_CONDED(strh)
DEF_ASM_CONDED(stmda)
DEF_ASM_CONDED(ldmda)
DEF_ASM_CONDED(stm)
DEF_ASM_CONDED(ldm)
DEF_ASM_CONDED(stmia)
DEF_ASM_CONDED(ldmia)
DEF_ASM_CONDED(stmdb)
DEF_ASM_CONDED(ldmdb)
DEF_ASM_CONDED(stmib)
DEF_ASM_CONDED(ldmib)
DEF_ASM_CONDED(ldc)
DEF_ASM_CONDED(ldcl)
DEF_ASM_CONDED(stc)
DEF_ASM_CONDED(stcl)
/* instruction macros */
DEF_ASM_CONDED(push)
DEF_ASM_CONDED(pop)
/* branches */
DEF_ASM_CONDED(b)
DEF_ASM_CONDED(bl)
DEF_ASM_CONDED(bx)
DEF_ASM_CONDED(blx)
/* data processing instructions; order is important */
DEF_ASM_CONDED(and)
DEF_ASM_CONDED(ands)
DEF_ASM_CONDED(eor)
DEF_ASM_CONDED(eors)
DEF_ASM_CONDED(sub)
DEF_ASM_CONDED(subs)
DEF_ASM_CONDED(rsb)
DEF_ASM_CONDED(rsbs)
DEF_ASM_CONDED(add)
DEF_ASM_CONDED(adds)
DEF_ASM_CONDED(adc)
DEF_ASM_CONDED(adcs)
DEF_ASM_CONDED(sbc)
DEF_ASM_CONDED(sbcs)
DEF_ASM_CONDED(rsc)
DEF_ASM_CONDED(rscs)
DEF_ASM_CONDED(tst)
DEF_ASM_CONDED(tsts) // necessary here--but not useful to the user
DEF_ASM_CONDED(teq)
DEF_ASM_CONDED(teqs) // necessary here--but not useful to the user
DEF_ASM_CONDED(cmp)
DEF_ASM_CONDED(cmps) // necessary here--but not useful to the user
DEF_ASM_CONDED(cmn)
DEF_ASM_CONDED(cmns) // necessary here--but not useful to the user
DEF_ASM_CONDED(orr)
DEF_ASM_CONDED(orrs)
DEF_ASM_CONDED(mov)
DEF_ASM_CONDED(movs)
DEF_ASM_CONDED(bic)
DEF_ASM_CONDED(bics)
DEF_ASM_CONDED(mvn)
DEF_ASM_CONDED(mvns)
DEF_ASM_CONDED(lsl)
DEF_ASM_CONDED(lsls)
DEF_ASM_CONDED(lsr)
DEF_ASM_CONDED(lsrs)
DEF_ASM_CONDED(asr)
DEF_ASM_CONDED(asrs)
DEF_ASM_CONDED(ror)
DEF_ASM_CONDED(rors)
DEF_ASM_CONDED(rrx)
DEF_ASM_CONDED(rrxs)
DEF_ASM_CONDED(cdp)
DEF_ASM_CONDED(mcr)
DEF_ASM_CONDED(mrc)
// Floating point high-level instructions
DEF_ASM_CONDED(vldr)
DEF_ASM_CONDED(vstr)
DEF_ASM_CONDED_VFP_F32_F64(vmla)
DEF_ASM_CONDED_VFP_F32_F64(vmls)
DEF_ASM_CONDED_VFP_F32_F64(vnmls)
DEF_ASM_CONDED_VFP_F32_F64(vnmla)
DEF_ASM_CONDED_VFP_F32_F64(vmul)
DEF_ASM_CONDED_VFP_F32_F64(vnmul)
DEF_ASM_CONDED_VFP_F32_F64(vadd)
DEF_ASM_CONDED_VFP_F32_F64(vsub)
DEF_ASM_CONDED_VFP_F32_F64(vdiv)
DEF_ASM_CONDED_VFP_F32_F64(vneg)
DEF_ASM_CONDED_VFP_F32_F64(vabs)
DEF_ASM_CONDED_VFP_F32_F64(vsqrt)
DEF_ASM_CONDED_VFP_F32_F64(vcmp)
DEF_ASM_CONDED_VFP_F32_F64(vcmpe)
DEF_ASM_CONDED_VFP_F32_F64(vmov)
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvtr, s32, f64)
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvtr, s32, f32)
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvtr, u32, f64)
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvtr, u32, f32)
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, s32, f64)
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, s32, f32)
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, u32, f64)
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, u32, f32)
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f64, s32)
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f32, s32)
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f64, u32)
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f32, u32)
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f64, f32)
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f32, f64)
DEF_ASM_CONDED(vpush)
DEF_ASM_CONDED(vpop)
DEF_ASM_CONDED(vldm)
DEF_ASM_CONDED(vldmia)
DEF_ASM_CONDED(vldmdb)
DEF_ASM_CONDED(vstm)
DEF_ASM_CONDED(vstmia)
DEF_ASM_CONDED(vstmdb)
DEF_ASM_CONDED(vmsr)
DEF_ASM_CONDED(vmrs)

2276
arm64-asm.c Normal file

File diff suppressed because it is too large Load Diff

2353
arm64-gen.c Normal file

File diff suppressed because it is too large Load Diff

406
arm64-link.c Normal file
View File

@ -0,0 +1,406 @@
#ifdef TARGET_DEFS_ONLY
#define EM_TCC_TARGET EM_AARCH64
#define R_DATA_32 R_AARCH64_ABS32
#define R_DATA_PTR R_AARCH64_ABS64
#define R_JMP_SLOT R_AARCH64_JUMP_SLOT
#define R_GLOB_DAT R_AARCH64_GLOB_DAT
#define R_COPY R_AARCH64_COPY
#define R_RELATIVE R_AARCH64_RELATIVE
#define R_NUM R_AARCH64_NUM
#define ELF_START_ADDR 0x00400000
#define ELF_PAGE_SIZE 0x10000
#define PCRELATIVE_DLLPLT 1
#define RELOCATE_DLLPLT 1
#else /* !TARGET_DEFS_ONLY */
#include "tcc.h"
#ifdef NEED_RELOC_TYPE
/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
relocations, returns -1. */
ST_FUNC int code_reloc (int reloc_type)
{
switch (reloc_type) {
case R_AARCH64_ABS32:
case R_AARCH64_ABS64:
case R_AARCH64_PREL32:
case R_AARCH64_MOVW_UABS_G0_NC:
case R_AARCH64_MOVW_UABS_G1_NC:
case R_AARCH64_MOVW_UABS_G2_NC:
case R_AARCH64_MOVW_UABS_G3:
case R_AARCH64_ADR_PREL_PG_HI21:
case R_AARCH64_ADD_ABS_LO12_NC:
case R_AARCH64_ADR_GOT_PAGE:
case R_AARCH64_LD64_GOT_LO12_NC:
case R_AARCH64_LDST128_ABS_LO12_NC:
case R_AARCH64_LDST64_ABS_LO12_NC:
case R_AARCH64_LDST32_ABS_LO12_NC:
case R_AARCH64_LDST16_ABS_LO12_NC:
case R_AARCH64_LDST8_ABS_LO12_NC:
case R_AARCH64_TLSLE_ADD_TPREL_HI12:
case R_AARCH64_TLSLE_ADD_TPREL_LO12:
case R_AARCH64_GLOB_DAT:
case R_AARCH64_COPY:
return 0;
case R_AARCH64_JUMP26:
case R_AARCH64_CALL26:
case R_AARCH64_JUMP_SLOT:
case R_AARCH64_CONDBR19:
case R_AARCH64_TSTBR14:
return 1;
}
return -1;
}
/* Returns an enumerator to describe whether and when the relocation needs a
GOT and/or PLT entry to be created. See tcc.h for a description of the
different values. */
ST_FUNC int gotplt_entry_type (int reloc_type)
{
switch (reloc_type) {
case R_AARCH64_PREL32:
case R_AARCH64_MOVW_UABS_G0_NC:
case R_AARCH64_MOVW_UABS_G1_NC:
case R_AARCH64_MOVW_UABS_G2_NC:
case R_AARCH64_MOVW_UABS_G3:
case R_AARCH64_ADR_PREL_PG_HI21:
case R_AARCH64_ADD_ABS_LO12_NC:
case R_AARCH64_LDST128_ABS_LO12_NC:
case R_AARCH64_LDST64_ABS_LO12_NC:
case R_AARCH64_LDST32_ABS_LO12_NC:
case R_AARCH64_LDST16_ABS_LO12_NC:
case R_AARCH64_LDST8_ABS_LO12_NC:
case R_AARCH64_GLOB_DAT:
case R_AARCH64_JUMP_SLOT:
case R_AARCH64_COPY:
case R_AARCH64_CONDBR19:
case R_AARCH64_TSTBR14:
case R_AARCH64_TLSLE_ADD_TPREL_HI12:
case R_AARCH64_TLSLE_ADD_TPREL_LO12:
return NO_GOTPLT_ENTRY;
case R_AARCH64_ABS32:
case R_AARCH64_ABS64:
case R_AARCH64_JUMP26:
case R_AARCH64_CALL26:
return AUTO_GOTPLT_ENTRY;
case R_AARCH64_ADR_GOT_PAGE:
case R_AARCH64_LD64_GOT_LO12_NC:
return ALWAYS_GOTPLT_ENTRY;
}
return -1;
}
#ifdef NEED_BUILD_GOT
ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
{
Section *plt = s1->plt;
uint8_t *p;
unsigned plt_offset;
if (plt->data_offset == 0) {
section_ptr_add(plt, 32);
}
plt_offset = plt->data_offset;
p = section_ptr_add(plt, 16);
write32le(p, got_offset);
write32le(p + 4, (uint64_t) got_offset >> 32);
return plt_offset;
}
/* relocate the PLT: compute addresses and offsets in the PLT now that final
address for PLT and GOT are known (see fill_program_header) */
ST_FUNC void relocate_plt(TCCState *s1)
{
uint8_t *p, *p_end;
if (!s1->plt)
return;
p = s1->plt->data;
p_end = p + s1->plt->data_offset;
if (p < p_end) {
uint64_t plt = s1->plt->sh_addr;
uint64_t got = s1->got->sh_addr + 16;
uint64_t off = (got >> 12) - (plt >> 12);
if ((off + ((uint32_t)1 << 20)) >> 21)
tcc_error_noabort("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
write32le(p, ARM64_STP_X_PRE | ARM64_RT(16) | ARM64_RT2(30) |
ARM64_RN(31) | ARM64_IMM7(-2)); // stp x16,x30,[sp,#-16]!
write32le(p + 4, (ARM64_ADRP | ARM64_RD(16) | // adrp x16,...
(off & 0x1ffffc) << 3 | (off & 3) << 29));
write32le(p + 8, (ARM64_LDR_X | ARM64_RT(17) | ARM64_RN(16) | // ldr x17,[x16,#...]
(got & 0xff8) << 7));
write32le(p + 12, (ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RD(16) | ARM64_RN(16) | // add x16,x16,#...
(got & 0xfff) << 10));
write32le(p + 16, ARM64_BR | ARM64_RN(17)); // br x17
write32le(p + 20, ARM64_NOP); // nop
write32le(p + 24, ARM64_NOP); // nop
write32le(p + 28, ARM64_NOP); // nop
p += 32;
got = s1->got->sh_addr;
while (p < p_end) {
uint64_t pc = plt + (p - s1->plt->data);
uint64_t addr = got + read64le(p);
uint64_t off = (addr >> 12) - (pc >> 12);
if ((off + ((uint32_t)1 << 20)) >> 21)
tcc_error_noabort("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);
write32le(p, (ARM64_ADRP | ARM64_RD(16) | // adrp x16,...
(off & 0x1ffffc) << 3 | (off & 3) << 29));
write32le(p + 4, (ARM64_LDR_X | ARM64_RT(17) | ARM64_RN(16) | // ldr x17,[x16,#...]
(addr & 0xff8) << 7));
write32le(p + 8, (ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RD(16) | ARM64_RN(16) | // add x16,x16,#...
(addr & 0xfff) << 10));
write32le(p + 12, ARM64_BR | ARM64_RN(17)); // br x17
p += 16;
}
}
if (s1->plt->reloc) {
ElfW_Rel *rel;
p = s1->got->data;
for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {
write64le(p + rel->r_offset, s1->plt->sh_addr);
}
}
}
#endif
#endif
ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
{
int sym_index = ELFW(R_SYM)(rel->r_info), esym_index;
#ifdef DEBUG_RELOC
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
#endif
switch(type) {
case R_AARCH64_ABS64:
if ((s1->output_type & TCC_OUTPUT_DYN)) {
esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
qrel->r_offset = rel->r_offset;
if (esym_index) {
qrel->r_info = ELFW(R_INFO)(esym_index, R_AARCH64_ABS64);
qrel->r_addend = rel->r_addend;
qrel++;
break;
} else {
qrel->r_info = ELFW(R_INFO)(0, R_AARCH64_RELATIVE);
qrel->r_addend = read64le(ptr) + val;
qrel++;
}
}
add64le(ptr, val);
return;
case R_AARCH64_ABS32:
if (s1->output_type & TCC_OUTPUT_DYN) {
/* XXX: this logic may depend on TCC's codegen
now TCC uses R_AARCH64_RELATIVE even for a 64bit pointer */
qrel->r_offset = rel->r_offset;
qrel->r_info = ELFW(R_INFO)(0, R_AARCH64_RELATIVE);
/* Use sign extension! */
qrel->r_addend = (int)read32le(ptr) + val;
qrel++;
}
add32le(ptr, val);
return;
case R_AARCH64_PREL32:
if (s1->output_type == TCC_OUTPUT_DLL) {
/* DLL relocation */
esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
if (esym_index) {
qrel->r_offset = rel->r_offset;
qrel->r_info = ELFW(R_INFO)(esym_index, R_AARCH64_PREL32);
/* Use sign extension! */
qrel->r_addend = (int)read32le(ptr) + rel->r_addend;
qrel++;
break;
}
}
add32le(ptr, val - addr);
return;
case R_AARCH64_MOVW_UABS_G0_NC:
write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
(val & 0xffff) << 5));
return;
case R_AARCH64_MOVW_UABS_G1_NC:
write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
(val >> 16 & 0xffff) << 5));
return;
case R_AARCH64_MOVW_UABS_G2_NC:
write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
(val >> 32 & 0xffff) << 5));
return;
case R_AARCH64_MOVW_UABS_G3:
write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
(val >> 48 & 0xffff) << 5));
return;
case R_AARCH64_ADR_PREL_PG_HI21: {
uint64_t off = (val >> 12) - (addr >> 12);
#ifdef TCC_TARGET_PE
/* Weak undefined symbols resolve to address 0 on PE. ADRP cannot
encode that from the default 64-bit image base, so materialize
zero directly and let the paired ADD handle any low addend. */
if ((off + ((uint64_t)1 << 20)) >> 21) {
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
if (sym->st_shndx == SHN_UNDEF
&& ELFW(ST_BIND)(sym->st_info) == STB_WEAK) {
write32le(ptr, 0xd2800000 | (read32le(ptr) & 0x1f));
return;
}
tcc_error_noabort("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
}
#else
if ((off + ((uint64_t)1 << 20)) >> 21)
tcc_error_noabort("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
#endif
write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
(off & 0x1ffffc) << 3 | (off & 3) << 29));
return;
}
case R_AARCH64_ADD_ABS_LO12_NC:
case R_AARCH64_LDST8_ABS_LO12_NC:
write32le(ptr, ((read32le(ptr) & 0xffc003ff) |
(val & 0xfff) << 10));
return;
case R_AARCH64_LDST16_ABS_LO12_NC:
write32le(ptr, ((read32le(ptr) & 0xffc003ff) |
(val & 0xffe) << 9));
return;
case R_AARCH64_LDST32_ABS_LO12_NC:
write32le(ptr, ((read32le(ptr) & 0xffc003ff) |
(val & 0xffc) << 8));
return;
case R_AARCH64_LDST64_ABS_LO12_NC:
write32le(ptr, ((read32le(ptr) & 0xffc003ff) |
(val & 0xff8) << 7));
return;
case R_AARCH64_LDST128_ABS_LO12_NC:
write32le(ptr, ((read32le(ptr) & 0xffc003ff) |
(val & 0xff0) << 6));
return;
case R_AARCH64_CONDBR19:
/* Conditional branch: 19-bit signed offset, bits 23:5 */
#ifdef DEBUG_RELOC
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
(char *) symtab_section->link->data + sym->st_name);
#endif
if (((val - addr) + ((uint64_t)1 << 20)) & ~(uint64_t)0x1ffffc)
tcc_error_noabort("R_AARCH64_CONDBR19 relocation failed"
" (val=%lx, addr=%lx)", (long)val, (long)addr);
write32le(ptr, ((read32le(ptr) & 0xff00001f) |
(((val - addr) >> 2 & 0x7ffff) << 5)));
return;
case R_AARCH64_TSTBR14:
/* Test and branch: 14-bit signed offset, bits 20:5 */
#ifdef DEBUG_RELOC
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
(char *) symtab_section->link->data + sym->st_name);
#endif
if (((val - addr) + ((uint64_t)1 << 15)) & ~(uint64_t)0xfffc)
tcc_error_noabort("R_AARCH64_TSTBR14 relocation failed"
" (val=%lx, addr=%lx)", (long)val, (long)addr);
write32le(ptr, ((read32le(ptr) & 0xfff8001f) |
(((val - addr) >> 2 & 0x3fff) << 5)));
return;
case R_AARCH64_JUMP26:
case R_AARCH64_CALL26:
{
const char *name;
#ifdef DEBUG_RELOC
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
(char *) symtab_section->link->data + sym->st_name);
#endif
if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc) {
#ifdef TCC_TARGET_PE
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
if (sym->st_shndx == SHN_UNDEF
&& ELFW(ST_BIND)(sym->st_info) == STB_WEAK) {
write32le(ptr, ARM64_NOP); /* nop */
return;
}
#endif
name = (char *)symtab_section->link->data +
((ElfW(Sym) *)symtab_section->data)[sym_index].st_name;
tcc_error_noabort("R_AARCH64_(JUMP|CALL)26 relocation failed"
" for '%s' (val=%lx, addr=%lx)",
name, (long)val, (long)addr);
}
write32le(ptr, (0x14000000 |
(uint32_t)(type == R_AARCH64_CALL26) << 31 |
((val - addr) >> 2 & 0x3ffffff)));
return;
}
case R_AARCH64_ADR_GOT_PAGE: {
uint64_t off =
(((s1->got->sh_addr +
get_sym_attr(s1, sym_index, 0)->got_offset) >> 12) - (addr >> 12));
if ((off + ((uint64_t)1 << 20)) >> 21)
tcc_error_noabort("R_AARCH64_ADR_GOT_PAGE relocation failed");
write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
(off & 0x1ffffc) << 3 | (off & 3) << 29));
return;
}
case R_AARCH64_LD64_GOT_LO12_NC:
write32le(ptr,
((read32le(ptr) & 0xfff803ff) |
((s1->got->sh_addr +
get_sym_attr(s1, sym_index, 0)->got_offset) & 0xff8) << 7));
return;
case R_AARCH64_COPY:
return;
case R_AARCH64_GLOB_DAT:
case R_AARCH64_JUMP_SLOT:
/* They don't need addend */
#ifdef DEBUG_RELOC
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr,
val - rel->r_addend,
(char *) symtab_section->link->data + sym->st_name);
#endif
write64le(ptr, val - rel->r_addend);
return;
case R_AARCH64_TLSLE_ADD_TPREL_HI12:
case R_AARCH64_TLSLE_ADD_TPREL_LO12: {
addr_t tls_start = 0;
int i;
for (i = 1; i < s1->nb_sections; i++) {
Section *s = s1->sections[i];
if (s->sh_flags & SHF_TLS && s->sh_size) {
if (!tls_start || s->sh_addr < tls_start)
tls_start = s->sh_addr;
}
}
/* glibc arm64: tp points to tcbhead_t (DTV), TLS data starts after it */
int64_t tp_offset = val - tls_start + 16;
int64_t imm;
if (type == R_AARCH64_TLSLE_ADD_TPREL_HI12)
imm = (tp_offset >> 12) & 0xfff;
else
imm = tp_offset & 0xfff;
write32le(ptr, ((read32le(ptr) & 0xffc003ff) | (imm << 10)));
return;
}
case R_AARCH64_RELATIVE:
#ifdef TCC_TARGET_PE
add32le(ptr, val - s1->pe_imagebase);
#endif
/* do nothing */
return;
default:
fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n",
type, (unsigned)addr, ptr, (unsigned)val);
return;
}
}
#endif /* !TARGET_DEFS_ONLY */

840
arm64-tok.h Normal file
View File

@ -0,0 +1,840 @@
/* ------------------------------------------------------------------ */
/* ARM64 (AArch64) assembler token definitions for TCC */
/* General purpose registers - 64-bit */
DEF_ASM(x0)
DEF_ASM(x1)
DEF_ASM(x2)
DEF_ASM(x3)
DEF_ASM(x4)
DEF_ASM(x5)
DEF_ASM(x6)
DEF_ASM(x7)
DEF_ASM(x8)
DEF_ASM(x9)
DEF_ASM(x10)
DEF_ASM(x11)
DEF_ASM(x12)
DEF_ASM(x13)
DEF_ASM(x14)
DEF_ASM(x15)
DEF_ASM(x16)
DEF_ASM(x17)
DEF_ASM(x18)
DEF_ASM(x19)
DEF_ASM(x20)
DEF_ASM(x21)
DEF_ASM(x22)
DEF_ASM(x23)
DEF_ASM(x24)
DEF_ASM(x25)
DEF_ASM(x26)
DEF_ASM(x27)
DEF_ASM(x28)
DEF_ASM(x29)
DEF_ASM(x30)
/* General purpose registers - 32-bit */
DEF_ASM(w0)
DEF_ASM(w1)
DEF_ASM(w2)
DEF_ASM(w3)
DEF_ASM(w4)
DEF_ASM(w5)
DEF_ASM(w6)
DEF_ASM(w7)
DEF_ASM(w8)
DEF_ASM(w9)
DEF_ASM(w10)
DEF_ASM(w11)
DEF_ASM(w12)
DEF_ASM(w13)
DEF_ASM(w14)
DEF_ASM(w15)
DEF_ASM(w16)
DEF_ASM(w17)
DEF_ASM(w18)
DEF_ASM(w19)
DEF_ASM(w20)
DEF_ASM(w21)
DEF_ASM(w22)
DEF_ASM(w23)
DEF_ASM(w24)
DEF_ASM(w25)
DEF_ASM(w26)
DEF_ASM(w27)
DEF_ASM(w28)
DEF_ASM(w29)
DEF_ASM(w30)
/* Special registers */
DEF_ASM(sp)
DEF_ASM(xzr)
DEF_ASM(wzr)
/* SIMD/FP registers - 128-bit views */
DEF_ASM(v0)
DEF_ASM(v1)
DEF_ASM(v2)
DEF_ASM(v3)
DEF_ASM(v4)
DEF_ASM(v5)
DEF_ASM(v6)
DEF_ASM(v7)
DEF_ASM(v8)
DEF_ASM(v9)
DEF_ASM(v10)
DEF_ASM(v11)
DEF_ASM(v12)
DEF_ASM(v13)
DEF_ASM(v14)
DEF_ASM(v15)
DEF_ASM(v16)
DEF_ASM(v17)
DEF_ASM(v18)
DEF_ASM(v19)
DEF_ASM(v20)
DEF_ASM(v21)
DEF_ASM(v22)
DEF_ASM(v23)
DEF_ASM(v24)
DEF_ASM(v25)
DEF_ASM(v26)
DEF_ASM(v27)
DEF_ASM(v28)
DEF_ASM(v29)
DEF_ASM(v30)
DEF_ASM(v31)
/* SIMD/FP registers - 64-bit views (double) */
DEF_ASM(d0)
DEF_ASM(d1)
DEF_ASM(d2)
DEF_ASM(d3)
DEF_ASM(d4)
DEF_ASM(d5)
DEF_ASM(d6)
DEF_ASM(d7)
DEF_ASM(d8)
DEF_ASM(d9)
DEF_ASM(d10)
DEF_ASM(d11)
DEF_ASM(d12)
DEF_ASM(d13)
DEF_ASM(d14)
DEF_ASM(d15)
DEF_ASM(d16)
DEF_ASM(d17)
DEF_ASM(d18)
DEF_ASM(d19)
DEF_ASM(d20)
DEF_ASM(d21)
DEF_ASM(d22)
DEF_ASM(d23)
DEF_ASM(d24)
DEF_ASM(d25)
DEF_ASM(d26)
DEF_ASM(d27)
DEF_ASM(d28)
DEF_ASM(d29)
DEF_ASM(d30)
DEF_ASM(d31)
/* SIMD/FP registers - 32-bit views (single) */
DEF_ASM(s0)
DEF_ASM(s1)
DEF_ASM(s2)
DEF_ASM(s3)
DEF_ASM(s4)
DEF_ASM(s5)
DEF_ASM(s6)
DEF_ASM(s7)
DEF_ASM(s8)
DEF_ASM(s9)
DEF_ASM(s10)
DEF_ASM(s11)
DEF_ASM(s12)
DEF_ASM(s13)
DEF_ASM(s14)
DEF_ASM(s15)
DEF_ASM(s16)
DEF_ASM(s17)
DEF_ASM(s18)
DEF_ASM(s19)
DEF_ASM(s20)
DEF_ASM(s21)
DEF_ASM(s22)
DEF_ASM(s23)
DEF_ASM(s24)
DEF_ASM(s25)
DEF_ASM(s26)
DEF_ASM(s27)
DEF_ASM(s28)
DEF_ASM(s29)
DEF_ASM(s30)
DEF_ASM(s31)
/* SIMD/FP registers - 16-bit views (half) */
DEF_ASM(h0)
DEF_ASM(h1)
DEF_ASM(h2)
DEF_ASM(h3)
DEF_ASM(h4)
DEF_ASM(h5)
DEF_ASM(h6)
DEF_ASM(h7)
DEF_ASM(h8)
DEF_ASM(h9)
DEF_ASM(h10)
DEF_ASM(h11)
DEF_ASM(h12)
DEF_ASM(h13)
DEF_ASM(h14)
DEF_ASM(h15)
DEF_ASM(h16)
DEF_ASM(h17)
DEF_ASM(h18)
DEF_ASM(h19)
DEF_ASM(h20)
DEF_ASM(h21)
DEF_ASM(h22)
DEF_ASM(h23)
DEF_ASM(h24)
DEF_ASM(h25)
DEF_ASM(h26)
DEF_ASM(h27)
DEF_ASM(h28)
DEF_ASM(h29)
DEF_ASM(h30)
DEF_ASM(h31)
/* SIMD/FP registers - 8-bit views (byte) */
DEF_ASM(b0)
DEF_ASM(b1)
DEF_ASM(b2)
DEF_ASM(b3)
DEF_ASM(b4)
DEF_ASM(b5)
DEF_ASM(b6)
DEF_ASM(b7)
DEF_ASM(b8)
DEF_ASM(b9)
DEF_ASM(b10)
DEF_ASM(b11)
DEF_ASM(b12)
DEF_ASM(b13)
DEF_ASM(b14)
DEF_ASM(b15)
DEF_ASM(b16)
DEF_ASM(b17)
DEF_ASM(b18)
DEF_ASM(b19)
DEF_ASM(b20)
DEF_ASM(b21)
DEF_ASM(b22)
DEF_ASM(b23)
DEF_ASM(b24)
DEF_ASM(b25)
DEF_ASM(b26)
DEF_ASM(b27)
DEF_ASM(b28)
DEF_ASM(b29)
DEF_ASM(b30)
DEF_ASM(b31)
/* Condition codes */
DEF_ASM(eq)
DEF_ASM(ne)
DEF_ASM(cs)
DEF_ASM(hs)
DEF_ASM(cc)
DEF_ASM(lo)
DEF_ASM(mi)
DEF_ASM(pl)
DEF_ASM(vs)
DEF_ASM(vc)
DEF_ASM(hi)
DEF_ASM(ls)
DEF_ASM(ge)
DEF_ASM(lt)
DEF_ASM(gt)
DEF_ASM(le)
DEF_ASM(al)
/* Data processing - arithmetic (no condition suffixes for ARM64) */
DEF_ASM(add)
DEF_ASM(adds)
DEF_ASM(sub)
DEF_ASM(subs)
DEF_ASM(cmn)
DEF_ASM(cmp)
DEF_ASM(neg)
DEF_ASM(negs)
DEF_ASM(adc)
DEF_ASM(adcs)
DEF_ASM(sbc)
DEF_ASM(sbcs)
DEF_ASM(ngc)
DEF_ASM(ngcs)
/* Data processing - bitwise */
DEF_ASM(and)
DEF_ASM(ands)
DEF_ASM(bic)
DEF_ASM(bics)
DEF_ASM(orr)
DEF_ASM(orn)
DEF_ASM(eor)
DEF_ASM(eon)
DEF_ASM(mvn)
DEF_ASM(mov)
/* Shifts */
DEF_ASM(lsl)
DEF_ASM(lsr)
DEF_ASM(asr)
DEF_ASM(ror)
/* Multiply/divide */
DEF_ASM(mul)
DEF_ASM(madd)
DEF_ASM(msub)
DEF_ASM(smaddl)
DEF_ASM(smsubl)
DEF_ASM(umaddl)
DEF_ASM(umsubl)
DEF_ASM(smulh)
DEF_ASM(umulh)
DEF_ASM(udiv)
DEF_ASM(sdiv)
/* Moves */
DEF_ASM(movz)
DEF_ASM(movn)
DEF_ASM(movk)
/* Compare/test */
DEF_ASM(tst)
DEF_ASM(teq)
/* Branch instructions */
DEF_ASM(b)
DEF_ASM(bl)
DEF_ASM(br)
DEF_ASM(blr)
DEF_ASM(ret)
DEF_ASM(cbz)
DEF_ASM(cbnz)
DEF_ASM(tbz)
DEF_ASM(tbnz)
/* Conditional branches */
DEF_ASM(beq)
DEF_ASM(bne)
DEF_ASM(bcs)
DEF_ASM(bhs)
DEF_ASM(bcc)
DEF_ASM(blo)
DEF_ASM(bmi)
DEF_ASM(bpl)
DEF_ASM(bvs)
DEF_ASM(bvc)
DEF_ASM(bhi)
DEF_ASM(bls)
DEF_ASM(bge)
DEF_ASM(blt)
DEF_ASM(bgt)
DEF_ASM(ble)
/* Conditional select */
DEF_ASM(csel)
DEF_ASM(csinc)
DEF_ASM(csinv)
DEF_ASM(csneg)
/* Load/Store */
DEF_ASM(ldr)
DEF_ASM(ldrb)
DEF_ASM(ldrh)
DEF_ASM(ldrsb)
DEF_ASM(ldrsh)
DEF_ASM(ldrsw)
DEF_ASM(str)
DEF_ASM(strb)
DEF_ASM(strh)
/* Load/Store - pair */
DEF_ASM(ldp)
DEF_ASM(stp)
DEF_ASM(ldpsw)
/* Address generation */
DEF_ASM(adr)
DEF_ASM(adrp)
/* System instructions */
DEF_ASM(mrs)
DEF_ASM(msr)
DEF_ASM(nop)
DEF_ASM(wfi)
DEF_ASM(wfe)
DEF_ASM(sev)
DEF_ASM(sevl)
DEF_ASM(isb)
DEF_ASM(dsb)
DEF_ASM(dmb)
/* Hints */
DEF_ASM(yield)
DEF_ASM(clrex)
/* Push/pop */
DEF_ASM(push)
DEF_ASM(pop)
/* Floating point */
DEF_ASM(fmov)
DEF_ASM(fadd)
DEF_ASM(fsub)
DEF_ASM(fmul)
DEF_ASM(fnmul)
DEF_ASM(fdiv)
DEF_ASM(fmax)
DEF_ASM(fmin)
DEF_ASM(fmaxnm)
DEF_ASM(fminnm)
DEF_ASM(fsqrt)
DEF_ASM(fabs)
DEF_ASM(fneg)
DEF_ASM(frintn)
DEF_ASM(frintp)
DEF_ASM(frintm)
DEF_ASM(frintz)
DEF_ASM(frinta)
DEF_ASM(frintx)
DEF_ASM(frinti)
DEF_ASM(fcmp)
DEF_ASM(fcmpe)
DEF_ASM(fccmp)
DEF_ASM(fccmpe)
DEF_ASM(fcvts)
DEF_ASM(fcvtd)
DEF_ASM(fcvth)
DEF_ASM(fcvtx)
DEF_ASM(scvtf)
DEF_ASM(ucvtf)
DEF_ASM(fcvtns)
DEF_ASM(fcvtnu)
DEF_ASM(fcvtps)
DEF_ASM(fcvtpu)
/* SIMD instructions */
DEF_ASM(addv)
DEF_ASM(faddp)
DEF_ASM(fmaxp)
DEF_ASM(fminp)
DEF_ASM(fmaxnmp)
DEF_ASM(fminnmp)
DEF_ASM(addp)
DEF_ASM(bif)
DEF_ASM(bit)
DEF_ASM(bsl)
DEF_ASM(dup)
DEF_ASM(ext)
DEF_ASM(ins)
DEF_ASM(movi)
DEF_ASM(mvni)
DEF_ASM(not)
DEF_ASM(shl)
DEF_ASM(shll)
DEF_ASM(shll2)
DEF_ASM(sli)
DEF_ASM(sri)
DEF_ASM(sqshl)
DEF_ASM(sqshlu)
DEF_ASM(srshl)
DEF_ASM(sshll)
DEF_ASM(sshll2)
DEF_ASM(sshr)
DEF_ASM(ushll)
DEF_ASM(ushll2)
DEF_ASM(ushr)
/* Misc */
DEF_ASM(bfm)
DEF_ASM(sbfm)
DEF_ASM(ubfm)
DEF_ASM(extr)
DEF_ASM(crc32b)
DEF_ASM(crc32h)
DEF_ASM(crc32w)
DEF_ASM(crc32x)
DEF_ASM(crc32cb)
DEF_ASM(crc32ch)
DEF_ASM(crc32cw)
DEF_ASM(crc32cx)
DEF_ASM(rev)
DEF_ASM(rev16)
DEF_ASM(rev32)
DEF_ASM(rev64)
DEF_ASM(clz)
DEF_ASM(cls)
DEF_ASM(rbit)
/* Exception generating */
DEF_ASM(svc)
DEF_ASM(hvc)
DEF_ASM(smc)
DEF_ASM(brk)
DEF_ASM(hlt)
DEF_ASM(dcps1)
DEF_ASM(dcps2)
DEF_ASM(dcps3)
/* Conditional branches */
DEF_ASM(b_eq)
DEF_ASM(b_ne)
DEF_ASM(b_cs)
DEF_ASM(b_cc)
DEF_ASM(b_mi)
DEF_ASM(b_pl)
DEF_ASM(b_vs)
DEF_ASM(b_vc)
DEF_ASM(b_hi)
DEF_ASM(b_ls)
DEF_ASM(b_ge)
DEF_ASM(b_lt)
DEF_ASM(b_gt)
DEF_ASM(b_le)
/* LD/ST exclusive */
DEF_ASM(ldxr)
DEF_ASM(ldxrb)
DEF_ASM(ldxrh)
DEF_ASM(stxr)
DEF_ASM(stxrb)
DEF_ASM(stxrh)
DEF_ASM(ldaxr)
DEF_ASM(ldaxrb)
DEF_ASM(ldaxrh)
DEF_ASM(stlxr)
DEF_ASM(stlxrb)
DEF_ASM(stlxrh)
/* LD/ST acquire-release */
DEF_ASM(ldar)
DEF_ASM(ldarb)
DEF_ASM(ldarh)
DEF_ASM(stlr)
DEF_ASM(stlrb)
DEF_ASM(stlrh)
DEF_ASM(ldalr)
DEF_ASM(ldalrb)
DEF_ASM(ldalrh)
DEF_ASM(stllr)
DEF_ASM(stllrb)
DEF_ASM(stllrh)
/* LD/ST unscaled immediate */
DEF_ASM(ldur)
DEF_ASM(ldurb)
DEF_ASM(ldurh)
DEF_ASM(ldursb)
DEF_ASM(ldursh)
DEF_ASM(ldursw)
DEF_ASM(stur)
DEF_ASM(sturb)
DEF_ASM(sturh)
/* Vector load/store */
DEF_ASM(ld1)
DEF_ASM(st1)
DEF_ASM(ld2)
DEF_ASM(st2)
DEF_ASM(ld3)
DEF_ASM(st3)
DEF_ASM(ld4)
DEF_ASM(st4)
/* ------------------------------------------------------------------ */
/* ARM64 instruction opcode constants and encoding helpers */
/* ------------------------------------------------------------------ */
/* Data processing - immediate */
#define ARM64_ADD_IMM 0x11000000U
#define ARM64_ADDS_IMM 0x2B000000U
#define ARM64_SUB_IMM 0x51000000U
#define ARM64_SUBS_IMM 0x6B000000U
/* Data processing - register */
#define ARM64_ADD_REG 0x0B000000U
#define ARM64_ADDS_REG 0x2B000000U
#define ARM64_SUB_REG 0x4B000000U
#define ARM64_SUBS_REG 0x6B000000U
#define ARM64_AND_REG 0x0A000000U
#define ARM64_ANDS_REG 0x6A000000U
#define ARM64_ORR_REG 0x2A000000U
#define ARM64_EOR_REG 0x4A000000U
#define ARM64_MUL_REG 0x1B000000U /* Base opcode, Rm/Rn/Rd must be filled in */
/* Move wide immediate */
#define ARM64_MOVZ 0x52800000U
#define ARM64_MOVN 0x12800000U
#define ARM64_MOVK 0xF2800000U
/* ARM64_MOVI_W/X removed: MOVI is a SIMD&FP instruction, not general-purpose */
/* Use MOVZ/MOVN/MOVK for general-purpose, or SIMD MOVI variants (0x0F000400, etc.) */
/* MOVZ/MOVN 64-bit base opcodes */
#define ARM64_MOVZ64 0xD2800000U /* MOVZ (64-bit), use with ARM64_HW() */
#define ARM64_MOVN64 0x92800000U /* MOVN (64-bit), use with ARM64_HW() */
/* Move wide immediate shift field (LSL #0/16/32/48 encoded as hw*16) */
#define ARM64_HW(v) (((uint32_t)(v) & 3) << 21)
/* Load/store register (unsigned immediate) */
#define ARM64_LDR_X 0xF9400000U
#define ARM64_LDR_W 0xB9400000U
#define ARM64_LDR_B 0x39400000U
#define ARM64_LDR_H 0x79400000U
#define ARM64_LDR_D 0xFD400000U
#define ARM64_LDR_S 0xBD400000U
#define ARM64_STR_X 0xF9000000U
#define ARM64_STR_W 0xB9000000U
#define ARM64_STR_B 0x39000000U
#define ARM64_STR_H 0x79000000U
#define ARM64_STR_D 0xFD000000U
#define ARM64_STR_S 0xBD000000U
/* Load/store register (unscaled immediate) */
#define ARM64_LDUR_X 0xF8400000U
#define ARM64_LDUR_W 0xB8400000U
#define ARM64_LDUR_B 0x38400000U
#define ARM64_LDUR_H 0x78400000U
#define ARM64_STUR_X 0xF8000000U
#define ARM64_STUR_W 0xB8000000U
#define ARM64_STUR_B 0x38000000U
#define ARM64_STUR_H 0x78000000U
/* Load/store register (register offset) */
#define ARM64_LDR_X_REG 0xF8606800U
#define ARM64_LDR_W_REG 0xB8606800U
#define ARM64_LDR_B_REG 0x38606800U
#define ARM64_LDR_H_REG 0x78606800U
#define ARM64_STR_X_REG 0xF8206800U
#define ARM64_STR_W_REG 0xB8206800U
#define ARM64_STR_B_REG 0x38206800U
#define ARM64_STR_H_REG 0x78206800U
/* Load/store (pre/post-indexed) */
#define ARM64_STR_X_PRE 0xF8000000U /* STR X pre-indexed base */
#define ARM64_LDR_X_POST 0xF8400000U /* LDR X post-indexed base */
/* SIMD load/store (unsigned immediate) */
#define ARM64_LDR_SCALAR 0x3D400000U /* Base for scalar load (size built dynamically) */
#define ARM64_LDR_S_VEC 0xBD400000U
#define ARM64_LDR_D_VEC 0xFD400000U
#define ARM64_LDR_Q_VEC 0x3DC00000U
#define ARM64_STR_SCALAR 0x3D000000U /* Base for scalar store (size built dynamically) */
#define ARM64_STR_S_VEC 0xBD000000U
#define ARM64_STR_D_VEC 0xFD000000U
#define ARM64_STR_Q_VEC 0x3D800000U
/* SIMD load/store (unscaled immediate) */
#define ARM64_LDUR_S_SIMD 0xBC400000U
#define ARM64_LDUR_D_SIMD 0xFC400000U
#define ARM64_LDUR_Q_SIMD 0x3C400000U
#define ARM64_STUR_S_SIMD 0xBC000000U
#define ARM64_STUR_D_SIMD 0xFC000000U
#define ARM64_STUR_Q_SIMD 0x3C000000U
/* SIMD load/store (register offset) */
#define ARM64_LDR_S_REG 0xBC606800U
#define ARM64_LDR_D_REG 0xFC606800U
#define ARM64_LDR_Q_REG 0x3C606800U
#define ARM64_STR_S_REG 0xBC206800U
#define ARM64_STR_D_REG 0xFC206800U
#define ARM64_STR_Q_REG 0x3C206800U
/* Load/store pair */
#define ARM64_LDP_X 0xA9400000U
#define ARM64_LDP_X_PRE 0xA9C00000U
#define ARM64_LDP_X_POST 0xA8C00000U
#define ARM64_STP_X 0xA9000000U
#define ARM64_STP_X_PRE 0xA9800000U
#define ARM64_STP_X_POST 0xA8800000U
#define ARM64_LDP_D 0x6D400000U
#define ARM64_LDP_D_PRE 0x6DC00000U
#define ARM64_LDP_D_POST 0x6CC00000U
#define ARM64_STP_D 0x6D000000U
#define ARM64_STP_D_PRE 0x6D800000U
#define ARM64_STP_D_POST 0x6C800000U
/* Branch instructions */
#define ARM64_B 0x14000000U
#define ARM64_BL 0x94000000U
#define ARM64_BR 0xD61F0000U
#define ARM64_BLR 0xD63F0000U
#define ARM64_RET 0xD65F0000U
/* Conditional branch */
#define ARM64_B_COND 0x54000000U
/* Compare and branch */
#define ARM64_CBZ 0x34000000U
#define ARM64_CBNZ 0x35000000U
/* System instructions */
#define ARM64_NOP 0xD503201FU
#define ARM64_ISB 0xD50330DFU
#define ARM64_DSB 0xD503309FU
#define ARM64_DMB 0xD50330BFU
#define ARM64_MRS 0xD5380000U
#define ARM64_MSR 0xD5180000U
#define ARM64_MRS_FPCR 0xD53B4400U
#define ARM64_MRS_FPSR 0xD53B4420U
#define ARM64_MSR_FPCR 0xD51B4400U
#define ARM64_MSR_FPSR 0xD51B4420U
/* Shifts (register) */
#define ARM64_LSL_REG 0x1AC02000U
#define ARM64_LSR_REG 0x1AC02400U
#define ARM64_ASR_REG 0x1AC02800U
#define ARM64_ROR_REG 0x1AC02C00U
/* Shifts (immediate - UBFM/SBFM) */
#define ARM64_LSL_IMM 0xD3400000U
#define ARM64_LSR_IMM 0xD3400000U
#define ARM64_LSR_IMM_32 0x53000000U /* 32-bit LSR base */
#define ARM64_ASR_IMM 0x93400000U
/* Shifted register encoding for ORR/AND/EOR */
#define ARM64_SHIFT_LSL(imm) (((uint32_t)(imm) & 63) << 10)
#define ARM64_SHIFT_LSR(imm) (0x00200000U | (((uint32_t)(imm) & 63) << 10))
#define ARM64_SHIFT_ASR(imm) (0x00400000U | (((uint32_t)(imm) & 63) << 10))
#define ARM64_SHIFT_ROR(imm) (0x00600000U | (((uint32_t)(imm) & 63) << 10))
/* UBFM/SBFM immediate fields (for LSL/LSR/ASR immediate aliases) */
#define ARM64_IMM_R(r) (((uint32_t)(r) & 0x3F) << 16)
#define ARM64_IMM_S(s) (((uint32_t)(s) & 0x3F) << 10)
/* Extended register encoding */
#define ARM64_EXTEND_LSL(lsl) (((uint32_t)(lsl) & 7) << 10)
/* MOV (register) - ORR with zero register */
#define ARM64_MOV_REG 0x2A0003E0U
/* Address generation */
#define ARM64_ADRP 0x90000000U
#define ARM64_ADR 0x10000000U
/* Logical immediate */
#define ARM64_AND_IMM 0x12000000U
#define ARM64_ORR_IMM_BASE 0x32000000U
#define ARM64_EOR_IMM 0x52000000U
#define ARM64_ANDS_IMM 0x72000000U
#define ARM64_ORR_IMM 0x320003E0U /* ORR immediate alias with Rn = XZR/WZR */
/* ------------------------------------------------------------------ */
/* ARM64 instruction encoding helper macros */
/* ------------------------------------------------------------------ */
/* Register field encodings */
#define ARM64_RD(r) ((uint32_t)(r) & 0x1FU)
#define ARM64_RN(r) (((uint32_t)(r) & 0x1FU) << 5)
#define ARM64_RM(r) (((uint32_t)(r) & 0x1FU) << 16)
#define ARM64_RT(r) ((uint32_t)(r) & 0x1FU)
#define ARM64_RT2(r) (((uint32_t)(r) & 0x1FU) << 10)
/* Immediate field encodings */
#define ARM64_IMM12(v) (((uint32_t)(v) & 0xFFFU) << 10)
#define ARM64_IMM7(v) (((uint32_t)(v) & 0x7FU) << 15)
#define ARM64_IMM14(v) (((uint32_t)(v) & 0x3FFFU) << 5)
#define ARM64_IMM16(v) (((uint32_t)(v) & 0xFFFFU) << 5)
#define ARM64_IMM_HW(v, hw) (((uint32_t)(v) & 0xFFFFU) << 5 | (((hw) & 3) << 21))
/* Shift and size encodings */
#define ARM64_SIZE(s) (((uint32_t)(s) & 3) << 30)
#define ARM64_SF(s) (((uint32_t)(s) & 1) << 31)
#define ARM64_S(v) (((uint32_t)(v) & 1) << 29)
#define ARM64_N(v) (((uint32_t)(v) & 1) << 22)
#define ARM64_SH(v) (((uint32_t)(v) & 1) << 22)
/* Condition code encoding */
#define ARM64_COND(c) ((uint32_t)(c) & 0xFU)
/* Branch offset encoding */
#define ARM64_OFFSET26(v) (((uint32_t)(v) >> 2) & 0x3FFFFFFU)
#define ARM64_OFFSET19(v) (((uint32_t)(v) >> 2) & 0x7FFFFU)
#define ARM64_OFFSET14(v) (((uint32_t)(v) >> 2) & 0x3FFFU)
/* Special register field (for MRS/MSR) */
#undef ARM64_SYSREG
#define ARM64_SYSREG(op0, op1, crn, crm, op2) \
((((op0) & 3) << 19) | (((op1) & 7) << 16) | \
(((crn) & 15) << 12) | (((crm) & 15) << 8) | (((op2) & 7) << 5))
/* Barrier option encoding */
#define ARM64_ISB_OPTION(opt) (((uint32_t)(opt) & 0xFU) << 8)
#define ARM64_DSB_OPTION(opt) (((uint32_t)(opt) & 0xFU) << 8)
#define ARM64_DMB_OPTION(opt) (((uint32_t)(opt) & 0xFU) << 8)
/* Additional opcodes for code generator - VERIFIED */
/* Note: Many of these are specific instances, not general templates */
/* Floating-point move - VERIFIED */
#define ARM64_FMOV_D_S 0x1E604000U /* FMOV Dd,Dn (scalar) */
#define ARM64_FMOV_X_D 0x9E660000U /* FMOV Xd,Dn (general to FP) */
#define ARM64_FMOV_W_S 0x1E260000U /* FMOV Wd,Sn (general to FP) */
/* ARM64_FMOV_S_D removed: 0x4EA01C00 is SIMD vector, not scalar FMOV */
/* Use 0x1E204000 for FMOV Sd,Sn or 0x1E604000 variant for cross-size */
/* FMOV variants for code generator */
#define ARM64_FMOV_SCALAR 0x1E604000U /* FMOV Dd, Dn (scalar FP) */
#define ARM64_FMOV_XD 0x9E660000U /* FMOV Xd, Dn (FP to GP 64-bit) */
#define ARM64_FMOV_WS 0x1E260000U /* FMOV Wd, Sn (FP to GP 32-bit) */
/* MOV vector (ORR vector register alias) */
#define ARM64_MOV_V16B 0x4EA01C00U /* MOV Vd.16B, Vn.16B (ORR vector, Rm=Rn alias) */
/* Load/Store SIMD&FP - Base opcodes (register fields must be filled in) */
#define ARM64_STR_Q_PRE 0x3C800000U /* STR Q pre-index base */
#define ARM64_LDR_Q_POST 0x3CC00000U /* LDR Q post-index base */
/* LDPSW - Base opcode (register fields must be filled in) */
/* Use gen_ldst_pair() with appropriate mode for LDPSW */
/* Base encodings: 0x68C00000 (post), 0x69400000 (offset), 0x69C00000 (pre) */
/* ARM64_LDR_S_SIMD removed: 0x0D00801C is not a standard encoding */
/* Use ARM64_LDR_S (0xBD400000) for scalar S or ARM64_LDR_S_VEC for SIMD */
/* MOV between SIMD and general - Use UMOV/SMOV instead */
/* ARM64_MOV_V_D removed: 0x4E083C00 is UMOV/SMOV encoding */
/* Use appropriate UMOV/SMOV base: 0x0E002C00/0x0E003C00 (32-bit) */
/* or 0x4E002C00/0x4E003C00 (64-bit) */
/* Verified from previous section */
#define ARM64_FCMP 0x1E202008U /* FCMP with zero */
#define ARM64_SDIV 0x1AC00C00U /* SDIV (32-bit) */
/* EXTR (Extract) */
#define ARM64_EXTR 0x13800000U /* EXTR Wd, Wn, Wm, #imm (32-bit) */
#define ARM64_EXTR64 0x93C00000U /* EXTR Xd, Xn, Xm, #imm (64-bit) */
/* ARM64_MUL removed - use ARM64_MUL_REG with gen_dp_reg() */
/* ORR shifted - Base opcodes (register fields must be filled in) */
#define ARM64_ORR_REG_LSL 0x2A000000U /* ORR (shifted register) base */
/* ARM64_ORR_REG_LSL32 removed: use ARM64_ORR_REG_LSL with SF=1 */
/* ARM64_ORR_REG_MOV is duplicate of ARM64_MOV_REG */
/* LSR immediate - These are UBFM encodings, use gen_shift() instead */
/* Base UBFM encodings: 0x53000000 (W), 0xD3400000 (X) */
/* gen_shift() handles immr/imms encoding for LSR/LSL/ASR */
/* ARM64_LSR_W_8, ARM64_LSR_X_8, ARM64_LSR_X_16, ARM64_LSR_X_24 removed */
/* They are specific instances, not templates */
/* SUB shifted - Base opcode (use gen_sub_reg or asm handler) */
#define ARM64_SUB_REG_LSL 0xCB000000U /* SUB (shifted register) base */
/* Duplicates removed: ARM64_LDP_X, ARM64_B, ARM64_BL, ARM64_BR, ARM64_NOP */
/* These are already defined in their respective sections above */

558
asmtest.S
View File

@ -1,558 +0,0 @@
/* some directive tests */
.byte 0xff
.byte 1, 2, 3
.short 1, 2, 3
.word 1, 2, 3
.long 1, 2, 3
.int 1, 2, 3
.align 8
.byte 1
.align 16, 0x90
.skip 3
.skip 15, 0x90
.string "hello\0world"
/* some label tests */
movl %eax, %ebx
L1:
movl %eax, %ebx
mov 0x10000, %eax
L2:
movl $L2 - L1, %ecx
var1:
nop ; nop ; nop ; nop
mov var1, %eax
/* instruction tests */
movl %eax, %ebx
mov 0x10000, %eax
mov 0x10000, %ax
mov 0x10000, %al
mov %al, 0x10000
mov $1, %edx
mov $1, %dx
mov $1, %dl
movb $2, 0x100(%ebx,%edx,2)
movw $2, 0x100(%ebx,%edx,2)
movl $2, 0x100(%ebx,%edx,2)
movl %eax, 0x100(%ebx,%edx,2)
movl 0x100(%ebx,%edx,2), %edx
movw %ax, 0x100(%ebx,%edx,2)
mov %eax, 0x12(,%edx,2)
mov %cr3, %edx
mov %ecx, %cr3
movl %cr3, %eax
movl %tr3, %eax
movl %db3, %ebx
movl %dr6, %eax
movl %fs, %ecx
movl %ebx, %fs
movsbl 0x1000, %eax
movsbw 0x1000, %ax
movswl 0x1000, %eax
movzbl 0x1000, %eax
movzbw 0x1000, %ax
movzwl 0x1000, %eax
movzb 0x1000, %eax
movzb 0x1000, %ax
pushl %eax
pushw %ax
push %eax
push %cs
push %gs
push $1
push $100
popl %eax
popw %ax
pop %eax
pop %ds
pop %fs
xchg %eax, %ecx
xchg %edx, %eax
xchg %bx, 0x10000
xchg 0x10000, %ebx
xchg 0x10000, %dl
in $100, %al
in $100, %ax
in $100, %eax
in %dx, %al
in %dx, %ax
in %dx, %eax
inb %dx
inw %dx
inl %dx
out %al, $100
out %ax, $100
out %eax, $100
/* NOTE: gas is bugged here, so size must be added */
outb %al, %dx
outw %ax, %dx
outl %eax, %dx
leal 0x1000(%ebx), %ecx
lea 0x1000(%ebx), %ecx
les 0x2000, %eax
lds 0x2000, %ebx
lfs 0x2000, %ecx
lgs 0x2000, %edx
lss 0x2000, %edx
addl $0x123, %eax
add $0x123, %ebx
addl $0x123, 0x100
addl $0x123, 0x100(%ebx)
addl $0x123, 0x100(%ebx,%edx,2)
addl $0x123, 0x100(%esp)
addl $0x123, (%ebp)
addl $0x123, (%esp)
cmpl $0x123, (%esp)
add %eax, (%ebx)
add (%ebx), %eax
or %dx, (%ebx)
or (%ebx), %si
add %cl, (%ebx)
add (%ebx), %dl
inc %edx
incl 0x10000
incb 0x10000
dec %dx
test $1, %al
test $1, %cl
testl $1, 0x1000
testb $1, 0x1000
testw $1, 0x1000
test %eax, %ebx
test %eax, 0x1000
test 0x1000, %edx
not %edx
notw 0x10000
notl 0x10000
notb 0x10000
neg %edx
negw 0x10000
negl 0x10000
negb 0x10000
imul %ecx
mul %edx
mulb %cl
imul %eax, %ecx
imul 0x1000, %cx
imul $10, %eax, %ecx
imul $10, %ax, %cx
imul $10, %eax
imul $0x1100000, %eax
imul $1, %eax
idivw 0x1000
div %ecx
div %bl
div %ecx, %eax
shl %edx
shl $10, %edx
shl %cl, %edx
shld $1, %eax, %edx
shld %cl, %eax, %edx
shld %eax, %edx
shrd $1, %eax, %edx
shrd %cl, %eax, %edx
shrd %eax, %edx
L4:
call 0x1000
call L4
call *%eax
call *0x1000
call func1
lcall $0x100, $0x1000
jmp 0x1000
jmp *%eax
jmp *0x1000
ljmp $0x100, $0x1000
ret
ret $10
lret
lret $10
enter $1234, $10
L3:
jo 0x1000
jnp 0x1001
jne 0x1002
jg 0x1003
jo L3
jnp L3
jne L3
jg L3
loopne L3
loopnz L3
loope L3
loopz L3
loop L3
jecxz L3
seto %al
setnp 0x1000
setl 0xaaaa
setg %dl
fadd
fadd %st(1), %st
fadd %st(3)
faddp %st(5)
faddp
faddp %st(1), %st
fadds 0x1000
fiadds 0x1002
faddl 0x1004
fiaddl 0x1006
fmul
fmul %st(1), %st
fmul %st(3)
fmulp %st(5)
fmulp
fmulp %st(1), %st
fmuls 0x1000
fimuls 0x1002
fmull 0x1004
fimull 0x1006
fsub
fsub %st(1), %st
fsub %st(3)
fsubp %st(5)
fsubp
fsubp %st(1), %st
fsubs 0x1000
fisubs 0x1002
fsubl 0x1004
fisubl 0x1006
fsubr
fsubr %st(1), %st
fsubr %st(3)
fsubrp %st(5)
fsubrp
fsubrp %st(1), %st
fsubrs 0x1000
fisubrs 0x1002
fsubrl 0x1004
fisubrl 0x1006
fdiv
fdiv %st(1), %st
fdiv %st(3)
fdivp %st(5)
fdivp
fdivp %st(1), %st
fdivs 0x1000
fidivs 0x1002
fdivl 0x1004
fidivl 0x1006
fcom %st(3)
fcoms 0x1000
ficoms 0x1002
fcoml 0x1004
ficoml 0x1006
fcomp %st(5)
fcomp
fcompp
fcomps 0x1000
ficomps 0x1002
fcompl 0x1004
ficompl 0x1006
fld %st(5)
fldl 0x1000
flds 0x1002
fildl 0x1004
fst %st(4)
fstp %st(6)
fstpt 0x1006
fbstp 0x1008
fxch
fxch %st(4)
fucom %st(6)
fucomp %st(3)
fucompp
finit
fninit
fldcw 0x1000
fnstcw 0x1002
fstcw 0x1002
fnstsw 0x1004
fnstsw %eax
fstsw 0x1004
fstsw %eax
fnclex
fclex
fnstenv 0x1000
fstenv 0x1000
fldenv 0x1000
fnsave 0x1002
fsave 0x1000
frstor 0x1000
ffree %st(7)
ffreep %st(6)
ftst
fxam
fld1
fldl2t
fldl2e
fldpi
fldlg2
fldln2
fldz
f2xm1
fyl2x
fptan
fpatan
fxtract
fprem1
fdecstp
fincstp
fprem
fyl2xp1
fsqrt
fsincos
frndint
fscale
fsin
fcos
fchs
fabs
fnop
fwait
bswap %edx
xadd %ecx, %edx
xaddb %dl, 0x1000
xaddw %ax, 0x1000
xaddl %eax, 0x1000
cmpxchg %ecx, %edx
cmpxchgb %dl, 0x1000
cmpxchgw %ax, 0x1000
cmpxchgl %eax, 0x1000
invlpg 0x1000
cmpxchg8b 0x1002
fcmovb %st(5), %st
fcmove %st(5), %st
fcmovbe %st(5), %st
fcmovu %st(5), %st
fcmovnb %st(5), %st
fcmovne %st(5), %st
fcmovnbe %st(5), %st
fcmovnu %st(5), %st
fcomi %st(5), %st
fucomi %st(5), %st
fcomip %st(5), %st
fucomip %st(5), %st
cmovo 0x1000, %eax
cmovs 0x1000, %eax
cmovns %edx, %edi
int $3
int $0x10
pusha
popa
clc
cld
cli
clts
cmc
lahf
sahf
pushfl
popfl
pushf
popf
stc
std
sti
aaa
aas
daa
das
aad
aam
cbw
cwd
cwde
cdq
cbtw
cwtd
cwtl
cltd
leave
int3
into
iret
rsm
hlt
wait
nop
/* XXX: handle prefixes */
#if 0
aword
addr16
#endif
lock
rep
repe
repz
repne
repnz
invd
wbinvd
cpuid
wrmsr
rdtsc
rdmsr
rdpmc
ud2
emms
movd %edx, %mm3
movd 0x1000, %mm2
movd %mm4, %ecx
movd %mm5, 0x1000
movq 0x1000, %mm2
movq %mm4, 0x1000
pand 0x1000, %mm3
pand %mm4, %mm5
psllw $1, %mm6
psllw 0x1000, %mm7
psllw %mm2, %mm7
xlat
cmpsb
scmpw
insl
outsw
lodsb
slodl
movsb
movsl
smovb
scasb
sscaw
stosw
sstol
bsf 0x1000, %ebx
bsr 0x1000, %ebx
bt %edx, 0x1000
btl $2, 0x1000
btc %edx, 0x1000
btcl $2, 0x1000
btr %edx, 0x1000
btrl $2, 0x1000
bts %edx, 0x1000
btsl $2, 0x1000
boundl %edx, 0x10000
boundw %bx, 0x1000
arpl %bx, 0x1000
lar 0x1000, %eax
lgdt 0x1000
lidt 0x1000
lldt 0x1000
lmsw 0x1000
lsl 0x1000, %ecx
ltr 0x1000
sgdt 0x1000
sidt 0x1000
sldt 0x1000
smsw 0x1000
str 0x1000
verr 0x1000
verw 0x1000
push %ds
pushw %ds
pushl %ds
pop %ds
popw %ds
popl %ds
fxsave 1(%ebx)
fxrstor 1(%ecx)
pushl $1
pushw $1
push $1

868
bcheck.c
View File

@ -1,868 +0,0 @@
/*
* Tiny C Memory and bounds checker
*
* Copyright (c) 2002 Fabrice Bellard
*
* This 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 of the License, or (at your option) any later version.
*
* This 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#if !defined(__FreeBSD__) && !defined(__DragonFly__) && !defined(__OpenBSD__)
#include <malloc.h>
#endif
//#define BOUND_DEBUG
/* define so that bound array is static (faster, but use memory if
bound checking not used) */
//#define BOUND_STATIC
/* use malloc hooks. Currently the code cannot be reliable if no hooks */
#define CONFIG_TCC_MALLOC_HOOKS
#define HAVE_MEMALIGN
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__dietlibc__) \
|| defined(__UCLIBC__) || defined(__OpenBSD__)
#warning Bound checking not fully supported in this environment.
#undef CONFIG_TCC_MALLOC_HOOKS
#undef HAVE_MEMALIGN
#endif
#define BOUND_T1_BITS 13
#define BOUND_T2_BITS 11
#define BOUND_T3_BITS (32 - BOUND_T1_BITS - BOUND_T2_BITS)
#define BOUND_T1_SIZE (1 << BOUND_T1_BITS)
#define BOUND_T2_SIZE (1 << BOUND_T2_BITS)
#define BOUND_T3_SIZE (1 << BOUND_T3_BITS)
#define BOUND_E_BITS 4
#define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS)
#define BOUND_T23_SIZE (1 << BOUND_T23_BITS)
/* this pointer is generated when bound check is incorrect */
#define INVALID_POINTER ((void *)(-2))
/* size of an empty region */
#define EMPTY_SIZE 0xffffffff
/* size of an invalid region */
#define INVALID_SIZE 0
typedef struct BoundEntry {
unsigned long start;
unsigned long size;
struct BoundEntry *next;
unsigned long is_invalid; /* true if pointers outside region are invalid */
} BoundEntry;
/* external interface */
void __bound_init(void);
void __bound_new_region(void *p, unsigned long size);
int __bound_delete_region(void *p);
#define FASTCALL __attribute__((regparm(3)))
void *__bound_malloc(size_t size, const void *caller);
void *__bound_memalign(size_t size, size_t align, const void *caller);
void __bound_free(void *ptr, const void *caller);
void *__bound_realloc(void *ptr, size_t size, const void *caller);
static void *libc_malloc(size_t size);
static void libc_free(void *ptr);
static void install_malloc_hooks(void);
static void restore_malloc_hooks(void);
#ifdef CONFIG_TCC_MALLOC_HOOKS
static void *saved_malloc_hook;
static void *saved_free_hook;
static void *saved_realloc_hook;
static void *saved_memalign_hook;
#endif
/* linker definitions */
extern char _end;
/* TCC definitions */
extern char __bounds_start; /* start of static bounds table */
/* error message, just for TCC */
const char *__bound_error_msg;
/* runtime error output */
extern void rt_error(unsigned long pc, const char *fmt, ...);
#ifdef BOUND_STATIC
static BoundEntry *__bound_t1[BOUND_T1_SIZE]; /* page table */
#else
static BoundEntry **__bound_t1; /* page table */
#endif
static BoundEntry *__bound_empty_t2; /* empty page, for unused pages */
static BoundEntry *__bound_invalid_t2; /* invalid page, for invalid pointers */
static BoundEntry *__bound_find_region(BoundEntry *e1, void *p)
{
unsigned long addr, tmp;
BoundEntry *e;
e = e1;
while (e != NULL) {
addr = (unsigned long)p;
addr -= e->start;
if (addr <= e->size) {
/* put region at the head */
tmp = e1->start;
e1->start = e->start;
e->start = tmp;
tmp = e1->size;
e1->size = e->size;
e->size = tmp;
return e1;
}
e = e->next;
}
/* no entry found: return empty entry or invalid entry */
if (e1->is_invalid)
return __bound_invalid_t2;
else
return __bound_empty_t2;
}
/* print a bound error message */
static void bound_error(const char *fmt, ...)
{
__bound_error_msg = fmt;
*(int *)0 = 0; /* force a runtime error */
}
static void bound_alloc_error(void)
{
bound_error("not enough memory for bound checking code");
}
/* currently, tcc cannot compile that because we use GNUC extensions */
#if !defined(__TINYC__)
/* return '(p + offset)' for pointer arithmetic (a pointer can reach
the end of a region in this case */
void * FASTCALL __bound_ptr_add(void *p, int offset)
{
unsigned long addr = (unsigned long)p;
BoundEntry *e;
#if defined(BOUND_DEBUG)
printf("add: 0x%x %d\n", (int)p, offset);
#endif
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
e = (BoundEntry *)((char *)e +
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
addr -= e->start;
if (addr > e->size) {
e = __bound_find_region(e, p);
addr = (unsigned long)p - e->start;
}
addr += offset;
if (addr > e->size)
return INVALID_POINTER; /* return an invalid pointer */
return p + offset;
}
/* return '(p + offset)' for pointer indirection (the resulting must
be strictly inside the region */
#define BOUND_PTR_INDIR(dsize) \
void * FASTCALL __bound_ptr_indir ## dsize (void *p, int offset) \
{ \
unsigned long addr = (unsigned long)p; \
BoundEntry *e; \
\
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; \
e = (BoundEntry *)((char *)e + \
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & \
((BOUND_T2_SIZE - 1) << BOUND_E_BITS))); \
addr -= e->start; \
if (addr > e->size) { \
e = __bound_find_region(e, p); \
addr = (unsigned long)p - e->start; \
} \
addr += offset + dsize; \
if (addr > e->size) \
return INVALID_POINTER; /* return an invalid pointer */ \
return p + offset; \
}
#ifdef __i386__
/* return the frame pointer of the caller */
#define GET_CALLER_FP(fp)\
{\
unsigned long *fp1;\
__asm__ __volatile__ ("movl %%ebp,%0" :"=g" (fp1));\
fp = fp1[0];\
}
#else
#error put code to extract the calling frame pointer
#endif
/* called when entering a function to add all the local regions */
void FASTCALL __bound_local_new(void *p1)
{
unsigned long addr, size, fp, *p = p1;
GET_CALLER_FP(fp);
for(;;) {
addr = p[0];
if (addr == 0)
break;
addr += fp;
size = p[1];
p += 2;
__bound_new_region((void *)addr, size);
}
}
/* called when leaving a function to delete all the local regions */
void FASTCALL __bound_local_delete(void *p1)
{
unsigned long addr, fp, *p = p1;
GET_CALLER_FP(fp);
for(;;) {
addr = p[0];
if (addr == 0)
break;
addr += fp;
p += 2;
__bound_delete_region((void *)addr);
}
}
#else
void __bound_local_new(void *p)
{
}
void __bound_local_delete(void *p)
{
}
void *__bound_ptr_add(void *p, int offset)
{
return p + offset;
}
#define BOUND_PTR_INDIR(dsize) \
void *__bound_ptr_indir ## dsize (void *p, int offset) \
{ \
return p + offset; \
}
#endif
BOUND_PTR_INDIR(1)
BOUND_PTR_INDIR(2)
BOUND_PTR_INDIR(4)
BOUND_PTR_INDIR(8)
BOUND_PTR_INDIR(12)
BOUND_PTR_INDIR(16)
static BoundEntry *__bound_new_page(void)
{
BoundEntry *page;
int i;
page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE);
if (!page)
bound_alloc_error();
for(i=0;i<BOUND_T2_SIZE;i++) {
/* put empty entries */
page[i].start = 0;
page[i].size = EMPTY_SIZE;
page[i].next = NULL;
page[i].is_invalid = 0;
}
return page;
}
/* currently we use malloc(). Should use bound_new_page() */
static BoundEntry *bound_new_entry(void)
{
BoundEntry *e;
e = libc_malloc(sizeof(BoundEntry));
return e;
}
static void bound_free_entry(BoundEntry *e)
{
libc_free(e);
}
static inline BoundEntry *get_page(int index)
{
BoundEntry *page;
page = __bound_t1[index];
if (page == __bound_empty_t2 || page == __bound_invalid_t2) {
/* create a new page if necessary */
page = __bound_new_page();
__bound_t1[index] = page;
}
return page;
}
/* mark a region as being invalid (can only be used during init) */
static void mark_invalid(unsigned long addr, unsigned long size)
{
unsigned long start, end;
BoundEntry *page;
int t1_start, t1_end, i, j, t2_start, t2_end;
start = addr;
end = addr + size;
t2_start = (start + BOUND_T3_SIZE - 1) >> BOUND_T3_BITS;
if (end != 0)
t2_end = end >> BOUND_T3_BITS;
else
t2_end = 1 << (BOUND_T1_BITS + BOUND_T2_BITS);
#if 0
printf("mark_invalid: start = %x %x\n", t2_start, t2_end);
#endif
/* first we handle full pages */
t1_start = (t2_start + BOUND_T2_SIZE - 1) >> BOUND_T2_BITS;
t1_end = t2_end >> BOUND_T2_BITS;
i = t2_start & (BOUND_T2_SIZE - 1);
j = t2_end & (BOUND_T2_SIZE - 1);
if (t1_start == t1_end) {
page = get_page(t2_start >> BOUND_T2_BITS);
for(; i < j; i++) {
page[i].size = INVALID_SIZE;
page[i].is_invalid = 1;
}
} else {
if (i > 0) {
page = get_page(t2_start >> BOUND_T2_BITS);
for(; i < BOUND_T2_SIZE; i++) {
page[i].size = INVALID_SIZE;
page[i].is_invalid = 1;
}
}
for(i = t1_start; i < t1_end; i++) {
__bound_t1[i] = __bound_invalid_t2;
}
if (j != 0) {
page = get_page(t1_end);
for(i = 0; i < j; i++) {
page[i].size = INVALID_SIZE;
page[i].is_invalid = 1;
}
}
}
}
void __bound_init(void)
{
int i;
BoundEntry *page;
unsigned long start, size;
int *p;
/* save malloc hooks and install bound check hooks */
install_malloc_hooks();
#ifndef BOUND_STATIC
__bound_t1 = libc_malloc(BOUND_T1_SIZE * sizeof(BoundEntry *));
if (!__bound_t1)
bound_alloc_error();
#endif
__bound_empty_t2 = __bound_new_page();
for(i=0;i<BOUND_T1_SIZE;i++) {
__bound_t1[i] = __bound_empty_t2;
}
page = __bound_new_page();
for(i=0;i<BOUND_T2_SIZE;i++) {
/* put invalid entries */
page[i].start = 0;
page[i].size = INVALID_SIZE;
page[i].next = NULL;
page[i].is_invalid = 1;
}
__bound_invalid_t2 = page;
/* invalid pointer zone */
start = (unsigned long)INVALID_POINTER & ~(BOUND_T23_SIZE - 1);
size = BOUND_T23_SIZE;
mark_invalid(start, size);
#if !defined(__TINYC__) && defined(CONFIG_TCC_MALLOC_HOOKS)
/* malloc zone is also marked invalid. can only use that with
hooks because all libs should use the same malloc. The solution
would be to build a new malloc for tcc. */
start = (unsigned long)&_end;
size = 128 * 0x100000;
mark_invalid(start, size);
#endif
/* add all static bound check values */
p = (int *)&__bounds_start;
while (p[0] != 0) {
__bound_new_region((void *)p[0], p[1]);
p += 2;
}
}
static inline void add_region(BoundEntry *e,
unsigned long start, unsigned long size)
{
BoundEntry *e1;
if (e->start == 0) {
/* no region : add it */
e->start = start;
e->size = size;
} else {
/* already regions in the list: add it at the head */
e1 = bound_new_entry();
e1->start = e->start;
e1->size = e->size;
e1->next = e->next;
e->start = start;
e->size = size;
e->next = e1;
}
}
/* create a new region. It should not already exist in the region list */
void __bound_new_region(void *p, unsigned long size)
{
unsigned long start, end;
BoundEntry *page, *e, *e2;
int t1_start, t1_end, i, t2_start, t2_end;
start = (unsigned long)p;
end = start + size;
t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
/* start */
page = get_page(t1_start);
t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
#ifdef BOUND_DEBUG
printf("new %lx %lx %x %x %x %x\n",
start, end, t1_start, t1_end, t2_start, t2_end);
#endif
e = (BoundEntry *)((char *)page + t2_start);
add_region(e, start, size);
if (t1_end == t1_start) {
/* same ending page */
e2 = (BoundEntry *)((char *)page + t2_end);
if (e2 > e) {
e++;
for(;e<e2;e++) {
e->start = start;
e->size = size;
}
add_region(e, start, size);
}
} else {
/* mark until end of page */
e2 = page + BOUND_T2_SIZE;
e++;
for(;e<e2;e++) {
e->start = start;
e->size = size;
}
/* mark intermediate pages, if any */
for(i=t1_start+1;i<t1_end;i++) {
page = get_page(i);
e2 = page + BOUND_T2_SIZE;
for(e=page;e<e2;e++) {
e->start = start;
e->size = size;
}
}
/* last page */
page = get_page(t1_end);
e2 = (BoundEntry *)((char *)page + t2_end);
for(e=page;e<e2;e++) {
e->start = start;
e->size = size;
}
add_region(e, start, size);
}
}
/* delete a region */
static inline void delete_region(BoundEntry *e,
void *p, unsigned long empty_size)
{
unsigned long addr;
BoundEntry *e1;
addr = (unsigned long)p;
addr -= e->start;
if (addr <= e->size) {
/* region found is first one */
e1 = e->next;
if (e1 == NULL) {
/* no more region: mark it empty */
e->start = 0;
e->size = empty_size;
} else {
/* copy next region in head */
e->start = e1->start;
e->size = e1->size;
e->next = e1->next;
bound_free_entry(e1);
}
} else {
/* find the matching region */
for(;;) {
e1 = e;
e = e->next;
/* region not found: do nothing */
if (e == NULL)
break;
addr = (unsigned long)p - e->start;
if (addr <= e->size) {
/* found: remove entry */
e1->next = e->next;
bound_free_entry(e);
break;
}
}
}
}
/* WARNING: 'p' must be the starting point of the region. */
/* return non zero if error */
int __bound_delete_region(void *p)
{
unsigned long start, end, addr, size, empty_size;
BoundEntry *page, *e, *e2;
int t1_start, t1_end, t2_start, t2_end, i;
start = (unsigned long)p;
t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
/* find region size */
page = __bound_t1[t1_start];
e = (BoundEntry *)((char *)page + t2_start);
addr = start - e->start;
if (addr > e->size)
e = __bound_find_region(e, p);
/* test if invalid region */
if (e->size == EMPTY_SIZE || (unsigned long)p != e->start)
return -1;
/* compute the size we put in invalid regions */
if (e->is_invalid)
empty_size = INVALID_SIZE;
else
empty_size = EMPTY_SIZE;
size = e->size;
end = start + size;
/* now we can free each entry */
t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
delete_region(e, p, empty_size);
if (t1_end == t1_start) {
/* same ending page */
e2 = (BoundEntry *)((char *)page + t2_end);
if (e2 > e) {
e++;
for(;e<e2;e++) {
e->start = 0;
e->size = empty_size;
}
delete_region(e, p, empty_size);
}
} else {
/* mark until end of page */
e2 = page + BOUND_T2_SIZE;
e++;
for(;e<e2;e++) {
e->start = 0;
e->size = empty_size;
}
/* mark intermediate pages, if any */
/* XXX: should free them */
for(i=t1_start+1;i<t1_end;i++) {
page = get_page(i);
e2 = page + BOUND_T2_SIZE;
for(e=page;e<e2;e++) {
e->start = 0;
e->size = empty_size;
}
}
/* last page */
page = get_page(t2_end);
e2 = (BoundEntry *)((char *)page + t2_end);
for(e=page;e<e2;e++) {
e->start = 0;
e->size = empty_size;
}
delete_region(e, p, empty_size);
}
return 0;
}
/* return the size of the region starting at p, or EMPTY_SIZE if non
existant region. */
static unsigned long get_region_size(void *p)
{
unsigned long addr = (unsigned long)p;
BoundEntry *e;
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
e = (BoundEntry *)((char *)e +
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
addr -= e->start;
if (addr > e->size)
e = __bound_find_region(e, p);
if (e->start != (unsigned long)p)
return EMPTY_SIZE;
return e->size;
}
/* patched memory functions */
static void install_malloc_hooks(void)
{
#ifdef CONFIG_TCC_MALLOC_HOOKS
saved_malloc_hook = __malloc_hook;
saved_free_hook = __free_hook;
saved_realloc_hook = __realloc_hook;
saved_memalign_hook = __memalign_hook;
__malloc_hook = __bound_malloc;
__free_hook = __bound_free;
__realloc_hook = __bound_realloc;
__memalign_hook = __bound_memalign;
#endif
}
static void restore_malloc_hooks(void)
{
#ifdef CONFIG_TCC_MALLOC_HOOKS
__malloc_hook = saved_malloc_hook;
__free_hook = saved_free_hook;
__realloc_hook = saved_realloc_hook;
__memalign_hook = saved_memalign_hook;
#endif
}
static void *libc_malloc(size_t size)
{
void *ptr;
restore_malloc_hooks();
ptr = malloc(size);
install_malloc_hooks();
return ptr;
}
static void libc_free(void *ptr)
{
restore_malloc_hooks();
free(ptr);
install_malloc_hooks();
}
/* XXX: we should use a malloc which ensure that it is unlikely that
two malloc'ed data have the same address if 'free' are made in
between. */
void *__bound_malloc(size_t size, const void *caller)
{
void *ptr;
/* we allocate one more byte to ensure the regions will be
separated by at least one byte. With the glibc malloc, it may
be in fact not necessary */
ptr = libc_malloc(size + 1);
if (!ptr)
return NULL;
__bound_new_region(ptr, size);
return ptr;
}
void *__bound_memalign(size_t size, size_t align, const void *caller)
{
void *ptr;
restore_malloc_hooks();
#ifndef HAVE_MEMALIGN
if (align > 4) {
/* XXX: handle it ? */
ptr = NULL;
} else {
/* we suppose that malloc aligns to at least four bytes */
ptr = malloc(size + 1);
}
#else
/* we allocate one more byte to ensure the regions will be
separated by at least one byte. With the glibc malloc, it may
be in fact not necessary */
ptr = memalign(size + 1, align);
#endif
install_malloc_hooks();
if (!ptr)
return NULL;
__bound_new_region(ptr, size);
return ptr;
}
void __bound_free(void *ptr, const void *caller)
{
if (ptr == NULL)
return;
if (__bound_delete_region(ptr) != 0)
bound_error("freeing invalid region");
libc_free(ptr);
}
void *__bound_realloc(void *ptr, size_t size, const void *caller)
{
void *ptr1;
int old_size;
if (size == 0) {
__bound_free(ptr, caller);
return NULL;
} else {
ptr1 = __bound_malloc(size, caller);
if (ptr == NULL || ptr1 == NULL)
return ptr1;
old_size = get_region_size(ptr);
if (old_size == EMPTY_SIZE)
bound_error("realloc'ing invalid pointer");
memcpy(ptr1, ptr, old_size);
__bound_free(ptr, caller);
return ptr1;
}
}
#ifndef CONFIG_TCC_MALLOC_HOOKS
void *__bound_calloc(size_t nmemb, size_t size)
{
void *ptr;
size = size * nmemb;
ptr = __bound_malloc(size, NULL);
if (!ptr)
return NULL;
memset(ptr, 0, size);
return ptr;
}
#endif
#if 0
static void bound_dump(void)
{
BoundEntry *page, *e;
int i, j;
printf("region dump:\n");
for(i=0;i<BOUND_T1_SIZE;i++) {
page = __bound_t1[i];
for(j=0;j<BOUND_T2_SIZE;j++) {
e = page + j;
/* do not print invalid or empty entries */
if (e->size != EMPTY_SIZE && e->start != 0) {
printf("%08x:",
(i << (BOUND_T2_BITS + BOUND_T3_BITS)) +
(j << BOUND_T3_BITS));
do {
printf(" %08lx:%08lx", e->start, e->start + e->size);
e = e->next;
} while (e != NULL);
printf("\n");
}
}
}
}
#endif
/* some useful checked functions */
/* check that (p ... p + size - 1) lies inside 'p' region, if any */
static void __bound_check(const void *p, size_t size)
{
if (size == 0)
return;
p = __bound_ptr_add((void *)p, size);
if (p == INVALID_POINTER)
bound_error("invalid pointer");
}
void *__bound_memcpy(void *dst, const void *src, size_t size)
{
__bound_check(dst, size);
__bound_check(src, size);
/* check also region overlap */
if (src >= dst && src < dst + size)
bound_error("overlapping regions in memcpy()");
return memcpy(dst, src, size);
}
void *__bound_memmove(void *dst, const void *src, size_t size)
{
__bound_check(dst, size);
__bound_check(src, size);
return memmove(dst, src, size);
}
void *__bound_memset(void *dst, int c, size_t size)
{
__bound_check(dst, size);
return memset(dst, c, size);
}
/* XXX: could be optimized */
int __bound_strlen(const char *s)
{
const char *p;
int len;
len = 0;
for(;;) {
p = __bound_ptr_indir1((char *)s, len);
if (p == INVALID_POINTER)
bound_error("bad pointer in strlen()");
if (*p == '\0')
break;
len++;
}
return len;
}
char *__bound_strcpy(char *dst, const char *src)
{
int len;
len = __bound_strlen(src);
return __bound_memcpy(dst, src, len + 1);
}

305
c67-gen.c
View File

@ -18,7 +18,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//#define ASSEMBLY_LISTING_C67
#ifdef TARGET_DEFS_ONLY
/* #define ASSEMBLY_LISTING_C67 */
/* number of available registers */
#define NB_REGS 24
@ -54,7 +56,7 @@
#define RC_C67_B12 0x04000000
#define RC_C67_B13 0x08000000
#define RC_IRET RC_C67_A4 /* function return: integer register */
#define RC_LRET RC_C67_A5 /* function return: second integer register */
#define RC_IRE2 RC_C67_A5 /* function return: second integer register */
#define RC_FRET RC_C67_A4 /* function return: float register */
/* pretty names for the registers */
@ -85,12 +87,45 @@ enum {
TREG_C67_B13,
};
int reg_classes[NB_REGS] = {
/* eax */ RC_INT | RC_FLOAT | RC_EAX,
// only allow even regs for floats (allow for doubles)
/* return registers for function */
#define REG_IRET TREG_C67_A4 /* single word int return register */
#define REG_IRE2 TREG_C67_A5 /* second word return register (for long long) */
#define REG_FRET TREG_C67_A4 /* float return register */
/* defined if function parameters must be evaluated in reverse order */
/* #define INVERT_FUNC_PARAMS */
/* defined if structures are passed as pointers. Otherwise structures
are directly pushed on stack. */
/* #define FUNC_STRUCT_PARAM_AS_PTR */
/* pointer size, in bytes */
#define PTR_SIZE 4
/* long double size and alignment, in bytes */
#define LDOUBLE_SIZE 12
#define LDOUBLE_ALIGN 4
/* maximum alignment (for aligned attribute support) */
#define MAX_ALIGN 8
#undef CONFIG_TCC_BCHECK
/******************************************************/
#else /* ! TARGET_DEFS_ONLY */
/******************************************************/
#define USING_GLOBALS
#include "tcc.h"
ST_DATA const char * const target_machine_defs =
"__C67__\0"
;
ST_DATA const int reg_classes[NB_REGS] = {
/* eax */ RC_INT | RC_FLOAT | RC_EAX,
// only allow even regs for floats (allow for doubles)
/* ecx */ RC_INT | RC_ECX,
/* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
// only allow even regs for floats (allow for doubles)
/* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
// only allow even regs for floats (allow for doubles)
/* st0 */ RC_INT | RC_INT_BSIDE | RC_ST0,
/* A4 */ RC_C67_A4,
/* A5 */ RC_C67_A5,
@ -114,67 +149,36 @@ int reg_classes[NB_REGS] = {
/* B13 */ RC_C67_B11
};
/* return registers for function */
#define REG_IRET TREG_C67_A4 /* single word int return register */
#define REG_LRET TREG_C67_A5 /* second word return register (for long long) */
#define REG_FRET TREG_C67_A4 /* float return register */
#define ALWAYS_ASSERT(x) \
do {\
if (!(x))\
error("internal compiler error file at %s:%d", __FILE__, __LINE__);\
} while (0)
// although tcc thinks it is passing parameters on the stack,
// the C67 really passes up to the first 10 params in special
// regs or regs pairs (for 64 bit params). So keep track of
// the stack offsets so we can translate to the appropriate
// reg (pair)
#define NoCallArgsPassedOnStack 10
int NoOfCurFuncArgs;
int TranslateStackToReg[NoCallArgsPassedOnStack];
int ParamLocOnStack[NoCallArgsPassedOnStack];
int TotalBytesPushedOnStack;
/* defined if function parameters must be evaluated in reverse order */
#ifndef FALSE
# define FALSE 0
# define TRUE 1
#endif
//#define INVERT_FUNC_PARAMS
#undef BOOL
#define BOOL int
/* defined if structures are passed as pointers. Otherwise structures
are directly pushed on stack. */
//#define FUNC_STRUCT_PARAM_AS_PTR
/* pointer size, in bytes */
#define PTR_SIZE 4
/* long double size and alignment, in bytes */
#define LDOUBLE_SIZE 12
#define LDOUBLE_ALIGN 4
/* maximum alignment (for aligned attribute support) */
#define MAX_ALIGN 8
#define ALWAYS_ASSERT(x) \
do {\
if (!(x))\
tcc_error("internal compiler error file at %s:%d", __FILE__, __LINE__);\
} while (0)
/******************************************************/
/* ELF defines */
#define EM_TCC_TARGET EM_C60
/* relocation type for 32 bit data relocation */
#define R_DATA_32 R_C60_32
#define R_JMP_SLOT R_C60_JMP_SLOT
#define R_COPY R_C60_COPY
#define ELF_START_ADDR 0x00000400
#define ELF_PAGE_SIZE 0x1000
/******************************************************/
static unsigned long func_sub_sp_offset;
static int func_ret_sub;
static BOOL C67_invert_test;
static int C67_compare_reg;
@ -182,11 +186,11 @@ static int C67_compare_reg;
FILE *f = NULL;
#endif
void C67_g(int c)
{
int ind1;
if (nocode_wanted)
return;
#ifdef ASSEMBLY_LISTING_C67
fprintf(f, " %08X", c);
#endif
@ -229,21 +233,16 @@ void gsym_addr(int t, int a)
}
}
void gsym(int t)
{
gsym_addr(t, ind);
}
// these are regs that tcc doesn't really know about,
// but asign them unique values so the mapping routines
// can distinquish them
// but assign them unique values so the mapping routines
// can distinguish them
#define C67_A0 105
#define C67_SP 106
#define C67_B3 107
#define C67_FP 108
#define C67_B2 109
#define C67_CREG_ZERO -1 // Special code for no condition reg test
#define C67_CREG_ZERO -1 /* Special code for no condition reg test */
int ConvertRegToRegClass(int r)
@ -372,7 +371,7 @@ int C67_map_D12(char *s)
void C67_asm(char *s, int a, int b, int c)
void C67_asm(const char *s, int a, int b, int c)
{
BOOL xpath;
@ -1552,23 +1551,23 @@ void C67_SHR(int r, int v)
void load(int r, SValue * sv)
{
int v, t, ft, fc, fr, size = 0, element;
BOOL Unsigned = false;
BOOL Unsigned = FALSE;
SValue v1;
fr = sv->r;
ft = sv->type.t;
fc = sv->c.ul;
fc = sv->c.i;
v = fr & VT_VALMASK;
if (fr & VT_LVAL) {
if (v == VT_LLOCAL) {
v1.type.t = VT_INT;
v1.r = VT_LOCAL | VT_LVAL;
v1.c.ul = fc;
v1.c.i = fc;
load(r, &v1);
fr = r;
} else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
error("long double not supported");
tcc_error("long double not supported");
} else if ((ft & VT_TYPE) == VT_BYTE) {
size = 1;
} else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
@ -1716,13 +1715,13 @@ void store(int r, SValue * v)
int fr, bt, ft, fc, size, t, element;
ft = v->type.t;
fc = v->c.ul;
fc = v->c.i;
fr = v->r & VT_VALMASK;
bt = ft & VT_BTYPE;
/* XXX: incorrect if float reg to reg */
if (bt == VT_LDOUBLE) {
error("long double not supported");
tcc_error("long double not supported");
} else {
if (bt == VT_SHORT)
size = 2;
@ -1869,6 +1868,13 @@ static void gcall_or_jmp(int is_jmp)
}
}
/* Return the number of registers needed to return the struct, or 0 if
returning via struct pointer. */
ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) {
*ret_align = 1; // Never have to re-align return values for x86-64
return 0;
}
/* generate function call with address in (vtop->t, vtop->c) and free function
context. Stack entry is popped */
void gfunc_call(int nb_args)
@ -1877,24 +1883,22 @@ void gfunc_call(int nb_args)
int args_sizes[NoCallArgsPassedOnStack];
if (nb_args > NoCallArgsPassedOnStack) {
error("more than 10 function params not currently supported");
tcc_error("more than 10 function params not currently supported");
// handle more than 10, put some on the stack
}
for (i = 0; i < nb_args; i++) {
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
ALWAYS_ASSERT(FALSE);
} else if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
ALWAYS_ASSERT(FALSE);
} else {
/* simple type (currently always same size) */
/* XXX: implicit cast ? */
if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
error("long long not supported");
tcc_error("long long not supported");
} else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
error("long double not supported");
tcc_error("long double not supported");
} else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
size = 8;
} else {
@ -1942,18 +1946,18 @@ void gfunc_call(int nb_args)
// parameters are loaded and restored upon return (or if/when needed).
/* generate function prolog of type 't' */
void gfunc_prolog(CType * func_type)
void gfunc_prolog(Sym *func_sym)
{
CType *func_type = &func_sym->type;
int addr, align, size, func_call, i;
Sym *sym;
CType *type;
sym = func_type->ref;
func_call = sym->r;
func_call = sym->f.func_call;
addr = 8;
/* if the function returns a structure, then add an
implicit pointer parameter */
func_vt = sym->type;
if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
func_vc = addr;
addr += 4;
@ -1964,7 +1968,7 @@ void gfunc_prolog(CType * func_type)
/* define parameters */
while ((sym = sym->next) != NULL) {
type = &sym->type;
sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr);
gfunc_set_param(sym, addr, 0);
size = type_size(type, &align);
size = (size + 3) & ~3;
@ -2032,10 +2036,22 @@ void gfunc_epilog(void)
}
}
ST_FUNC void gen_fill_nops(int bytes)
{
if ((bytes & 3))
tcc_error("alignment of code section not multiple of 4");
while (bytes > 0) {
C67_NOP(4);
bytes -= 4;
}
}
/* generate a jump to a label */
int gjmp(int t)
{
int ind1 = ind;
if (nocode_wanted)
return t;
C67_MVKL(C67_A0, t); //r=reg to load, constant
C67_MVKH(C67_A0, t); //r=reg to load, constant
@ -2062,13 +2078,13 @@ void gjmp_addr(int a)
}
/* generate a test. set 'inv' to invert test. Stack entry is popped */
int gtst(int inv, int t)
ST_FUNC int gjmp_cond(int op, int t)
{
int ind1, n;
int v, *p;
int ind1;
int inv = op & 1;
if (nocode_wanted)
return t;
v = vtop->r & VT_VALMASK;
if (v == VT_CMP) {
/* fast case : can jump directly since flags are set */
// C67 uses B2 sort of as flags register
ind1 = ind;
@ -2086,17 +2102,18 @@ int gtst(int inv, int t)
C67_NOP(5);
t = ind1; //return where we need to patch
} else if (v == VT_JMP || v == VT_JMPI) {
/* && or || optimization */
if ((v & 1) == inv) {
return t;
}
ST_FUNC int gjmp_append(int n0, int t)
{
if (n0) {
int n = n0, *p;
/* insert vtop->c jump list in t */
p = &vtop->c.i;
// I guess the idea is to traverse to the
// null at the end of the list and store t
// there
n = *p;
while (n != 0) {
p = (int *) (cur_text_section->data + n);
@ -2106,45 +2123,8 @@ int gtst(int inv, int t)
}
*p |= (t & 0xffff) << 7;
*(p + 1) |= ((t >> 16) & 0xffff) << 7;
t = vtop->c.i;
} else {
t = gjmp(t);
gsym(vtop->c.i);
}
} else {
if (is_float(vtop->type.t)) {
vpushi(0);
gen_op(TOK_NE);
}
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
/* constant jmp optimization */
if ((vtop->c.i != 0) != inv)
t = gjmp(t);
} else {
// I think we need to get the value on the stack
// into a register, test it, and generate a branch
// return the address of the branch, so it can be
// later patched
v = gv(RC_INT); // get value into a reg
ind1 = ind;
C67_MVKL(C67_A0, t); //r=reg to load, constant
C67_MVKH(C67_A0, t); //r=reg to load, constant
if (v != TREG_EAX && // check if not already in a conditional test reg
v != TREG_EDX && v != TREG_ST0 && v != C67_B2) {
C67_MV(v, C67_B2);
v = C67_B2;
}
C67_IREG_B_REG(inv, v, C67_A0); // [!R] B.S2x A0
C67_NOP(5);
t = ind1; //return where we need to patch
ind1 = ind;
}
t = n0;
}
vtop--;
return t;
}
@ -2178,34 +2158,34 @@ void gen_opi(int op)
if (op == TOK_LT) {
C67_CMPLT(r, fr, C67_B2);
C67_invert_test = false;
C67_invert_test = FALSE;
} else if (op == TOK_GE) {
C67_CMPLT(r, fr, C67_B2);
C67_invert_test = true;
C67_invert_test = TRUE;
} else if (op == TOK_GT) {
C67_CMPGT(r, fr, C67_B2);
C67_invert_test = false;
C67_invert_test = FALSE;
} else if (op == TOK_LE) {
C67_CMPGT(r, fr, C67_B2);
C67_invert_test = true;
C67_invert_test = TRUE;
} else if (op == TOK_EQ) {
C67_CMPEQ(r, fr, C67_B2);
C67_invert_test = false;
C67_invert_test = FALSE;
} else if (op == TOK_NE) {
C67_CMPEQ(r, fr, C67_B2);
C67_invert_test = true;
C67_invert_test = TRUE;
} else if (op == TOK_ULT) {
C67_CMPLTU(r, fr, C67_B2);
C67_invert_test = false;
C67_invert_test = FALSE;
} else if (op == TOK_UGE) {
C67_CMPLTU(r, fr, C67_B2);
C67_invert_test = true;
C67_invert_test = TRUE;
} else if (op == TOK_UGT) {
C67_CMPGTU(r, fr, C67_B2);
C67_invert_test = false;
C67_invert_test = FALSE;
} else if (op == TOK_ULE) {
C67_CMPGTU(r, fr, C67_B2);
C67_invert_test = true;
C67_invert_test = TRUE;
} else if (op == '+')
C67_ADD(fr, r); // ADD r,fr,r
else if (op == '-')
@ -2220,10 +2200,8 @@ void gen_opi(int op)
ALWAYS_ASSERT(FALSE);
vtop--;
if (op >= TOK_ULT && op <= TOK_GT) {
vtop->r = VT_CMP;
vtop->c.i = op;
}
if (op >= TOK_ULT && op <= TOK_GT)
vset_VT_CMP(0x80);
break;
case '-':
case TOK_SUBC1: /* sub with carry generation */
@ -2250,7 +2228,7 @@ void gen_opi(int op)
r = vtop[-1].r;
fr = vtop[0].r;
vtop--;
C67_MPYI(fr, r); // 32 bit bultiply fr,r,fr
C67_MPYI(fr, r); // 32 bit multiply fr,r,fr
C67_NOP(8); // NOP 8 for worst case
break;
case TOK_SHL:
@ -2282,7 +2260,7 @@ void gen_opi(int op)
call_func:
vswap();
/* call generic idiv function */
vpush_global_sym(&func_old_type, t);
vpush_helper_func(t);
vrott(3);
gfunc_call(2);
vpushi(0);
@ -2307,7 +2285,7 @@ void gen_opi(int op)
}
/* generate a floating point operation 'v = t1 op t2' instruction. The
two operands are guaranted to have the same floating point type */
two operands are guaranteed to have the same floating point type */
/* XXX: need to use ST1 too */
void gen_opf(int op)
{
@ -2319,13 +2297,13 @@ void gen_opf(int op)
gv2(RC_FLOAT, RC_FLOAT); // make sure src2 is on b side
ft = vtop->type.t;
fc = vtop->c.ul;
fc = vtop->c.i;
r = vtop->r;
fr = vtop[-1].r;
if ((ft & VT_BTYPE) == VT_LDOUBLE)
error("long doubles not supported");
tcc_error("long doubles not supported");
if (op >= TOK_ULT && op <= TOK_GT) {
@ -2340,46 +2318,46 @@ void gen_opf(int op)
else
C67_CMPLTSP(r, fr, C67_B2);
C67_invert_test = false;
C67_invert_test = FALSE;
} else if (op == TOK_GE) {
if ((ft & VT_BTYPE) == VT_DOUBLE)
C67_CMPLTDP(r, fr, C67_B2);
else
C67_CMPLTSP(r, fr, C67_B2);
C67_invert_test = true;
C67_invert_test = TRUE;
} else if (op == TOK_GT) {
if ((ft & VT_BTYPE) == VT_DOUBLE)
C67_CMPGTDP(r, fr, C67_B2);
else
C67_CMPGTSP(r, fr, C67_B2);
C67_invert_test = false;
C67_invert_test = FALSE;
} else if (op == TOK_LE) {
if ((ft & VT_BTYPE) == VT_DOUBLE)
C67_CMPGTDP(r, fr, C67_B2);
else
C67_CMPGTSP(r, fr, C67_B2);
C67_invert_test = true;
C67_invert_test = TRUE;
} else if (op == TOK_EQ) {
if ((ft & VT_BTYPE) == VT_DOUBLE)
C67_CMPEQDP(r, fr, C67_B2);
else
C67_CMPEQSP(r, fr, C67_B2);
C67_invert_test = false;
C67_invert_test = FALSE;
} else if (op == TOK_NE) {
if ((ft & VT_BTYPE) == VT_DOUBLE)
C67_CMPEQDP(r, fr, C67_B2);
else
C67_CMPEQSP(r, fr, C67_B2);
C67_invert_test = true;
C67_invert_test = TRUE;
} else {
ALWAYS_ASSERT(FALSE);
}
vtop->r = VT_CMP; // tell TCC that result is in "flags" actually B2
vset_VT_CMP(0x80);
} else {
if (op == '+') {
if ((ft & VT_BTYPE) == VT_DOUBLE) {
@ -2413,18 +2391,18 @@ void gen_opf(int op)
// must call intrinsic DP floating point divide
vswap();
/* call generic idiv function */
vpush_global_sym(&func_old_type, TOK__divd);
vpush_helper_func(TOK__divd);
vrott(3);
gfunc_call(2);
vpushi(0);
vtop->r = REG_FRET;
vtop->r2 = REG_LRET;
vtop->r2 = REG_IRE2;
} else {
// must call intrinsic SP floating point divide
vswap();
/* call generic idiv function */
vpush_global_sym(&func_old_type, TOK__divf);
vpush_helper_func(TOK__divf);
vrott(3);
gfunc_call(2);
vpushi(0);
@ -2477,7 +2455,7 @@ void gen_cvt_ftoi(int t)
r = vtop->r;
if (t != VT_INT)
error("long long not supported");
tcc_error("long long not supported");
else {
if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
C67_DPTRUNC(r, r);
@ -2544,5 +2522,22 @@ void ggoto(void)
vtop--;
}
/* end of X86 code generator */
/* Save the stack pointer onto the stack and return the location of its address */
ST_FUNC void gen_vla_sp_save(int addr) {
tcc_error("variable length arrays unsupported for this target");
}
/* Restore the SP from a location on the stack */
ST_FUNC void gen_vla_sp_restore(int addr) {
tcc_error("variable length arrays unsupported for this target");
}
/* Subtract from the stack pointer, and push the resulting value onto the stack */
ST_FUNC void gen_vla_alloc(CType *type, int align) {
tcc_error("variable length arrays unsupported for this target");
}
/* end of C67 code generator */
/*************************************************************/
#endif
/*************************************************************/

125
c67-link.c Normal file
View File

@ -0,0 +1,125 @@
#ifdef TARGET_DEFS_ONLY
#define EM_TCC_TARGET EM_C60
/* relocation type for 32 bit data relocation */
#define R_DATA_32 R_C60_32
#define R_DATA_PTR R_C60_32
#define R_JMP_SLOT R_C60_JMP_SLOT
#define R_GLOB_DAT R_C60_GLOB_DAT
#define R_COPY R_C60_COPY
#define R_RELATIVE R_C60_RELATIVE
#define R_NUM R_C60_NUM
#define ELF_START_ADDR 0x00000400
#define ELF_PAGE_SIZE 0x1000
#define PCRELATIVE_DLLPLT 0
#define RELOCATE_DLLPLT 0
#else /* !TARGET_DEFS_ONLY */
#include "tcc.h"
/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
relocations, returns -1. */
ST_FUNC int code_reloc (int reloc_type)
{
switch (reloc_type) {
case R_C60_32:
case R_C60LO16:
case R_C60HI16:
case R_C60_GOT32:
case R_C60_GOTOFF:
case R_C60_GOTPC:
case R_C60_COPY:
return 0;
case R_C60_PLT32:
return 1;
}
return -1;
}
/* Returns an enumerator to describe whether and when the relocation needs a
GOT and/or PLT entry to be created. See tcc.h for a description of the
different values. */
ST_FUNC int gotplt_entry_type (int reloc_type)
{
switch (reloc_type) {
case R_C60_32:
case R_C60LO16:
case R_C60HI16:
case R_C60_COPY:
return NO_GOTPLT_ENTRY;
case R_C60_GOTOFF:
case R_C60_GOTPC:
return BUILD_GOT_ONLY;
case R_C60_PLT32:
case R_C60_GOT32:
return ALWAYS_GOTPLT_ENTRY;
}
return -1;
}
ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
{
tcc_error_noabort("C67 got not implemented");
return 0;
}
/* relocate the PLT: compute addresses and offsets in the PLT now that final
address for PLT and GOT are known (see fill_program_header) */
ST_FUNC void relocate_plt(TCCState *s1)
{
uint8_t *p, *p_end;
if (!s1->plt)
return;
p = s1->plt->data;
p_end = p + s1->plt->data_offset;
if (p < p_end) {
/* XXX: TODO */
while (p < p_end) {
/* XXX: TODO */
}
}
}
ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
{
switch(type) {
case R_C60_32:
*(int *)ptr += val;
break;
case R_C60LO16:
{
uint32_t orig;
/* put the low 16 bits of the absolute address add to what is
already there */
orig = ((*(int *)(ptr )) >> 7) & 0xffff;
orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
/* patch both at once - assumes always in pairs Low - High */
*(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) |
(((val+orig) & 0xffff) << 7);
*(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) |
((((val+orig)>>16) & 0xffff) << 7);
}
break;
case R_C60HI16:
break;
default:
fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
type, (unsigned) addr, ptr, (unsigned) val);
break;
}
}
#endif /* !TARGET_DEFS_ONLY */

8
coff.h
View File

@ -22,7 +22,7 @@ struct filehdr {
/*------------------------------------------------------------------------*/
#define F_RELFLG 0x01 /* relocation info stripped from file */
#define F_EXEC 0x02 /* file is executable (no unresolved refs) */
#define F_LNNO 0x04 /* line nunbers stripped from file */
#define F_LNNO 0x04 /* line numbers stripped from file */
#define F_LSYMS 0x08 /* local symbols stripped from file */
#define F_GSP10 0x10 /* 34010 version */
#define F_GSP20 0x20 /* 34020 version */
@ -37,8 +37,8 @@ struct filehdr {
#define F_BYTE_ORDER (F_LITTLE | F_BIG)
#define FILHDR struct filehdr
//#define FILHSZ sizeof(FILHDR)
#define FILHSZ 22 // above rounds to align on 4 bytes which causes problems
/* #define FILHSZ sizeof(FILHDR) */
#define FILHSZ 22 /* above rounds to align on 4 bytes which causes problems */
#define COFF_C67_MAGIC 0x00c2
@ -150,7 +150,7 @@ struct scnhdr {
/*------------------------------------------------------------------------*/
/* Define constants for names of "special" sections */
/*------------------------------------------------------------------------*/
//#define _TEXT ".text"
/* #define _TEXT ".text" */
#define _DATA ".data"
#define _BSS ".bss"
#define _CINIT ".cinit"

1035
configure vendored

File diff suppressed because it is too large Load Diff

308
conftest.c Normal file
View File

@ -0,0 +1,308 @@
/* ----------------------------------------------------------------------- */
/* with -D C2STR: convert tccdefs.h to C-strings */
#if C2STR
#include <stdio.h>
#include <string.h>
/* replace native host macros by compile-time versions */
const char *platform_macros[] = {
"__i386__", "TCC_TARGET_I386",
"__x86_64__", "TCC_TARGET_X86_64",
"_WIN32", "TCC_TARGET_PE",
"__arm__", "TCC_TARGET_ARM",
"__ARM_EABI__", "TCC_ARM_EABI",
"__aarch64__", "TCC_TARGET_ARM64",
"__riscv", "TCC_TARGET_RISCV64",
"__APPLE__", "TCC_TARGET_MACHO",
"__FreeBSD__", "TARGETOS_FreeBSD",
"__FreeBSD_kernel__", "TARGETOS_FreeBSD_kernel",
"__OpenBSD__", "TARGETOS_OpenBSD",
"__NetBSD__", "TARGETOS_NetBSD",
"__linux__", "TARGETOS_Linux",
"__ANDROID__", "TARGETOS_ANDROID",
"__SIZEOF_POINTER__", "PTR_SIZE",
"__SIZEOF_LONG__", "LONG_SIZE",
0
};
int isid(int c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
|| (c >= '0' && c <= '9') || c == '_';
}
int isspc(int c)
{
return (unsigned char)c <= ' ' && c != 0;
}
int main(int argc, char **argv)
{
char l[1000], l2[1000], *p, *q, *p0;
FILE *fp, *op;
int c, e, f, s, cmt, cmt_n;
const char *r;
if (argc < 3)
return 1;
fp = fopen(argv[1], "rb");
op = fopen(argv[2], "wb");
if (!fp || !op) {
fprintf(stderr, "c2str: file error\n");
return 1;
}
cmt = cmt_n = 0;
for (;;) {
p = l;
append:
if (fgets(p, sizeof l - (p - l), fp)) {
p = strchr(p, 0);
while (p > l && isspc(p[-1]))
--p;
*p = 0;
} else if (p == l)
break;
/* check for continuation */
if (p > l && p[-1] == '\\') {
p[-1] = ' ';
goto append;
}
/* count & skip leading spaces */
p = l, q = l2, f = 0;
while (*p && isspc(*p))
++p, ++f;
/* handle comments */
if (p[0] == '/' && cmt == 0) {
if (p[1] == '*')
cmt = 2;
if (p[1] == '/')
cmt = 1;
}
if (cmt) {
fprintf(op, "%s", l);
if (++cmt_n == 1)
fprintf(op, " (converted, do not edit this file)");
fprintf(op, "\n");
if (cmt == 1)
cmt = 0;
if (cmt == 2) {
p = strchr(l, 0);
if (p >= l + 2 && p[-1] == '/' && p[-2] == '*')
cmt = 0;
}
continue;
}
if (f < 4) {
do {
/* replace machine/os macros by compile-time counterparts */
for (e = f = 0; (r = platform_macros[f]); f += 2) {
c = strlen(r);
/* remove 'defined' */
//e = memcmp(p, "defined ", 8) ? 0 : 8;
if (0 == memcmp(p + e, r, c)) {
p += e + c;
q = strchr(strcpy(q, platform_macros[f + 1]), 0);
break;
}
}
if (r)
continue;
} while (!!(*q++ = *p++));
/* output as is */
fprintf(op, "%s\n", l2);
continue;
} else {
s = e = f = 0, p0 = p;
for (;;) {
c = *p++;
if (isspc(c)) {
s = 1;
continue;
}
if (c == '/' && (p[0] == '/' || p[0] == '*'))
c = 0; /* trailing comment detected */
else if (s && q > l2
&& ((isid(q[-1]) && isid(c))
// keep space after macro name
|| (q >= l2 + 2
&& l2[0] == '#'
&& l2[1] == 'd'
&& f < 2 && !e
)))
*q++ = ' ', ++f;
s = 0;
if (c == '(')
++e;
if (c == ')')
--e;
if (c == '\\' || c == '\"')
*q++ = '\\';
*q++ = c;
if (c == 0)
break;
p0 = p;
}
/* output with quotes */
fprintf(op, " \"%s\\n\"%s\n", l2, p0);
}
}
fclose(fp);
fclose(op);
return 0;
}
/* ----------------------------------------------------------------------- */
/* get some information from the host compiler for configure */
#elif 1
#include <stdio.h>
#if defined(_WIN32)
#include <fcntl.h>
#include <io.h>
int _CRT_glob = 0;
#endif
/* Define architecture */
#if defined(__i386__) || defined _M_IX86
# define TRIPLET_ARCH "i386"
#elif defined(__x86_64__) || defined _M_AMD64
# define TRIPLET_ARCH "x86_64"
#elif defined(__arm__)
# define TRIPLET_ARCH "arm"
#elif defined(__aarch64__)
# define TRIPLET_ARCH "aarch64"
#elif defined(__riscv) && defined(__LP64__)
# define TRIPLET_ARCH "riscv64"
#else
# define TRIPLET_ARCH "unknown"
#endif
/* Define OS */
#if defined (__linux__)
# define TRIPLET_OS "linux"
#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
# define TRIPLET_OS "kfreebsd"
#elif defined(__NetBSD__)
# define TRIPLET_OS "netbsd"
#elif defined(__OpenBSD__)
# define TRIPLET_OS "openbsd"
#elif defined(_WIN32)
# define TRIPLET_OS "win32"
#elif defined(__APPLE__)
# define TRIPLET_OS "darwin"
#elif !defined (__GNU__)
# define TRIPLET_OS "unknown"
#endif
#if defined __ANDROID__
# define ABI_PREFIX "android"
#else
# define ABI_PREFIX "gnu"
#endif
/* Define calling convention and ABI */
#if defined (__ARM_EABI__)
# if defined (__ARM_PCS_VFP)
# define TRIPLET_ABI ABI_PREFIX"eabihf"
# else
# define TRIPLET_ABI ABI_PREFIX"eabi"
# endif
#else
# define TRIPLET_ABI ABI_PREFIX
#endif
#if defined _WIN32
# define TRIPLET TRIPLET_ARCH "-" TRIPLET_OS
#elif defined __GNU__
# define TRIPLET TRIPLET_ARCH "-" TRIPLET_ABI
#else
# define TRIPLET TRIPLET_ARCH "-" TRIPLET_OS "-" TRIPLET_ABI
#endif
int main(int argc, char *argv[])
{
#if defined(_WIN32)
_setmode(_fileno(stdout), _O_BINARY); /* don't translate \n to \r\n */
#endif
switch(argc == 2 ? argv[1][0] : 0) {
case 'b'://igendian
{
volatile unsigned foo = 0x01234567;
puts(*(unsigned char*)&foo == 0x67 ? "no" : "yes");
break;
}
#if defined(__clang__)
case 'm'://inor
printf("%d\n", __clang_minor__);
break;
case 'v'://ersion
printf("%d\n", __clang_major__);
break;
#elif defined(__TINYC__)
case 'v'://ersion
puts("0");
break;
case 'm'://inor
printf("%d\n", __TINYC__);
break;
#elif defined(_MSC_VER)
case 'v'://ersion
puts("0");
break;
case 'm'://inor
printf("%d\n", _MSC_VER);
break;
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
/* GNU comes last as other compilers may add 'GNU' compatibility */
case 'm'://inor
printf("%d\n", __GNUC_MINOR__);
break;
case 'v'://ersion
printf("%d\n", __GNUC__);
break;
#else
case 'm'://inor
case 'v'://ersion
puts("0");
break;
#endif
case 't'://riplet
puts(TRIPLET);
break;
case 'c'://ompiler
#if defined(__clang__)
puts("clang");
#elif defined(__TINYC__)
puts("tcc");
#elif defined(_MSC_VER)
puts("msvc");
#elif defined(__GNUC__)
puts("gcc");
#else
puts("unknown");
#endif
break;
default:
break;
}
return 0;
}
/* ----------------------------------------------------------------------- */
#endif

1046
dwarf.h Normal file

File diff suppressed because it is too large Load Diff

3678
elf.h

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#! /usr/local/bin/tcc -run
#!/usr/local/bin/tcc -run
#include <tcclib.h>
int main()
int main()
{
printf("Hello World\n");
return 0;

View File

@ -1,4 +1,5 @@
#include "tcclib.h"
#include <stdlib.h>
#include <stdio.h>
#define N 20
@ -23,7 +24,7 @@ int find(int n, int i1, int a, int b, int op)
return 1;
tab[i1] = n;
}
for(i=0;i<nb_num;i++) {
for(j=i+1;j<nb_num;j++) {
a = tab[i];
@ -52,7 +53,7 @@ int find(int n, int i1, int a, int b, int op)
if (find(c, i, b, a, '/'))
return 1;
}
stack_ptr--;
tab[i] = a;
tab[j] = b;
@ -66,7 +67,7 @@ int find(int n, int i1, int a, int b, int op)
int main(int argc, char **argv)
{
int i, res, p;
if (argc < 3) {
printf("usage: %s: result numbers...\n"
"Try to find result from numbers with the 4 basic operations.\n", argv[0]);
@ -85,7 +86,7 @@ int main(int argc, char **argv)
res = find(0, 0, 0, 0, ' ');
if (res) {
for(i=0;i<=stack_ptr;i++) {
printf("%d %c %d = %d\n",
printf("%d %c %d = %d\n",
stack_res[3*i], stack_op[i],
stack_res[3*i+1], stack_res[3*i+2]);
}

View File

@ -1,6 +1,6 @@
#include <tcclib.h>
int fib(n)
int fib(int n)
{
if (n <= 2)
return 1;
@ -8,7 +8,7 @@ int fib(n)
return fib(n-1) + fib(n-2);
}
int main(int argc, char **argv)
int main(int argc, char **argv)
{
int n;
if (argc < 2) {
@ -16,8 +16,8 @@ int main(int argc, char **argv)
"Compute nth Fibonacci number\n");
return 1;
}
n = atoi(argv[1]);
printf("fib(%d) = %d\n", n, fib(n, 2));
printf("fib(%d) = %d\n", n, fib(n));
return 0;
}

View File

@ -1,9 +1,10 @@
#!./tcc -run -L/usr/X11R6/lib -lX11
#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
#include <stdlib.h>
/* Yes, TCC can use X11 too ! */
#include <stdio.h>
#include <X11/Xlib.h>
/* Yes, TCC can use X11 too ! */
int main(int argc, char **argv)
{
Display *display;
@ -16,8 +17,8 @@ int main(int argc, char **argv)
}
printf("X11 display opened.\n");
screen = XScreenOfDisplay(display, 0);
printf("width = %d\nheight = %d\ndepth = %d\n",
screen->width,
printf("width = %d\nheight = %d\ndepth = %d\n",
screen->width,
screen->height,
screen->root_depth);
XCloseDisplay(display);

View File

@ -1,7 +1,7 @@
#include <stdlib.h>
#include <stdio.h>
int main()
int main()
{
printf("Hello World\n");
return 0;

View File

@ -1,33 +0,0 @@
#!/bin/sh
TESTSUITE_PATH=$HOME/gcc/gcc-3.2/gcc/testsuite/gcc.c-torture
TCC="./tcc -B. -I. -DNO_TRAMPOLINES"
rm -f tcc.sum tcc.log
nb_failed="0"
for src in $TESTSUITE_PATH/compile/*.c ; do
echo $TCC -o /tmp/test.o -c $src
$TCC -o /tmp/test.o -c $src >> tcc.log 2>&1
if [ "$?" == "0" ] ; then
result="PASS"
else
result="FAIL"
nb_failed=$[ $nb_failed + 1 ]
fi
echo "$result: $src" >> tcc.sum
done
for src in $TESTSUITE_PATH/execute/*.c ; do
echo $TCC $src
$TCC $src >> tcc.log 2>&1
if [ "$?" == "0" ] ; then
result="PASS"
else
result="FAIL"
nb_failed=$[ $nb_failed + 1 ]
fi
echo "$result: $src" >> tcc.sum
done
echo "$nb_failed test(s) failed." >> tcc.sum
echo "$nb_failed test(s) failed."

1249
i386-asm.c

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
DEF_ASM_OP0(popa, 0x61)
DEF_ASM_OP0(clc, 0xf8)
DEF_ASM_OP0(clc, 0xf8) /* must be first OP0 */
DEF_ASM_OP0(cld, 0xfc)
DEF_ASM_OP0(cli, 0xfa)
DEF_ASM_OP0(clts, 0x0f06)
DEF_ASM_OP0(cmc, 0xf5)
DEF_ASM_OP0(lahf, 0x9f)
DEF_ASM_OP0(sahf, 0x9e)
DEF_ASM_OP0(pusha, 0x60)
DEF_ASM_OP0(popa, 0x61)
DEF_ASM_OP0(pushfl, 0x9c)
DEF_ASM_OP0(popfl, 0x9d)
DEF_ASM_OP0(pushf, 0x9c)
@ -33,50 +33,60 @@
DEF_ASM_OP0(iret, 0xcf)
DEF_ASM_OP0(rsm, 0x0faa)
DEF_ASM_OP0(hlt, 0xf4)
DEF_ASM_OP0(wait, 0x9b)
DEF_ASM_OP0(nop, 0x90)
DEF_ASM_OP0(pause, 0xf390)
DEF_ASM_OP0(xlat, 0xd7)
/* strings */
ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
/* Control-Flow Enforcement */
DEF_ASM_OP0L(endbr32, 0xf30f1e, 7, OPC_MODRM)
/* strings */
ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLX))
ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLX))
ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWLX))
ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWLX))
ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWLX))
ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWLX))
ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWLX))
ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWLX))
ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWLX))
ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWLX))
/* bits */
ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP2(popcntw, 0xf30fb8, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
ALT(DEF_ASM_OP2(tzcntw, 0xf30fbc, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
ALT(DEF_ASM_OP2(lzcntw, 0xf30fbd, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
/* prefixes */
DEF_ASM_OP0(wait, 0x9b)
DEF_ASM_OP0(fwait, 0x9b)
DEF_ASM_OP0(aword, 0x67)
DEF_ASM_OP0(addr16, 0x67)
DEF_ASM_OP0(word, 0x66)
ALT(DEF_ASM_OP0(word, 0x66))
DEF_ASM_OP0(data16, 0x66)
DEF_ASM_OP0(lock, 0xf0)
DEF_ASM_OP0(rep, 0xf3)
@ -95,43 +105,43 @@ ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)
DEF_ASM_OP0(ud2, 0x0f0b)
/* NOTE: we took the same order as gas opcode definition order */
ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWLX, OPT_ADDR, OPT_EAX))
ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWLX, OPT_EAX, OPT_ADDR))
ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWLX, OPT_IM, OPT_REG))
ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WLX, OPT_SEG, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_SEG))
ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WLX, OPT_CR, OPT_REG32))
ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WLX, OPT_DB, OPT_REG32))
ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WLX, OPT_TR, OPT_REG32))
ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_CR))
ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_DB))
ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_TR))
ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
ALT(DEF_ASM_OP2(movsbw, 0x660fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG16))
ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WLX, OPT_REG8 | OPT_EA, OPT_REGW))
ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REGW))
ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WLX, OPT_IM8S))
ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WLX, OPT_IM32))
ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WLX, OPT_SEG))
ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REGW))
ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA))
ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WLX, OPT_SEG))
ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_REGW, OPT_EAX))
ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_EAX, OPT_REGW))
ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
@ -143,7 +153,7 @@ ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WLX, OPT_EA, OPT_REG))
ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
@ -152,77 +162,80 @@ ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
/* arith */
ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWLX, OPT_IM, OPT_EAX))
ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_EA | OPT_REGW))
ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWLX, OPT_IM, OPT_EAX))
ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WLX, OPT_REGW))
ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WLX, OPT_REGW))
ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW))
ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW))
ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
/* shifts */
ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_EA | OPT_REG))
ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP))
ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8))
ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA))
ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
ALT(DEF_ASM_OP1(ljmp, 0xff, 5, OPC_MODRM, OPT_EA))
ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
ALT(DEF_ASM_OP1(setob, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
DEF_ASM_OP0(leave, 0xc9)
DEF_ASM_OP0(ret, 0xc3)
DEF_ASM_OP0(retl,0xc3)
ALT(DEF_ASM_OP1(retl,0xc2, 0, 0, OPT_IM16))
ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
DEF_ASM_OP0(lret, 0xcb)
ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8))
DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8)
DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8)
DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8)
DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8)
DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8)
DEF_ASM_OP1(jecxz, 0xe3, 0, 0, OPT_DISP8)
/* float */
/* specific fcomp handling */
@ -230,6 +243,8 @@ ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
ALT(DEF_ASM_OP2(fadd, 0xdcc0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
ALT(DEF_ASM_OP2(fmul, 0xdcc8, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
@ -272,7 +287,6 @@ ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
DEF_ASM_OP0(fninit, 0xdbe3)
DEF_ASM_OP0(fnclex, 0xdbe2)
DEF_ASM_OP0(fnop, 0xd9d0)
DEF_ASM_OP0(fwait, 0x9b)
/* fp load */
DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
@ -335,12 +349,12 @@ ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
/* segments */
DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
ALT(DEF_ASM_OP2(larw, 0x0f02, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_REG))
DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
@ -352,19 +366,18 @@ ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
/* 486 */
DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
DEF_ASM_OP2(boundw, 0x6662, 0, OPC_MODRM, OPT_REG16, OPT_EA)
/* pentium */
DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
/* pentium pro */
ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
@ -381,62 +394,93 @@ ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT
/* mmx */
DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMXSSE )
DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG32 ))
ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
ALT(DEF_ASM_OP2(movq, 0x660fd6, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_SSE ))
ALT(DEF_ASM_OP2(movq, 0xf30f7e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ))
DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
/* sse */
DEF_ASM_OP1(ldmxcsr, 0x0fae, 2, OPC_MODRM, OPT_EA)
DEF_ASM_OP1(stmxcsr, 0x0fae, 3, OPC_MODRM, OPT_EA)
DEF_ASM_OP2(movups, 0x0f10, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
ALT(DEF_ASM_OP2(movups, 0x0f11, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
DEF_ASM_OP2(movaps, 0x0f28, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
ALT(DEF_ASM_OP2(movaps, 0x0f29, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
DEF_ASM_OP2(movhps, 0x0f16, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
DEF_ASM_OP2(addps, 0x0f58, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(cvtpi2ps, 0x0f2a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_SSE )
DEF_ASM_OP2(cvtps2pi, 0x0f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
DEF_ASM_OP2(cvttps2pi, 0x0f2c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
DEF_ASM_OP2(divps, 0x0f5e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(maxps, 0x0f5f, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(minps, 0x0f5d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(mulps, 0x0f59, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(pavgb, 0x0fe0, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(pavgw, 0x0fe3, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(pmaxsw, 0x0fee, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pmaxub, 0x0fde, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pminsw, 0x0fea, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(pminub, 0x0fda, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
DEF_ASM_OP2(rcpss, 0x0f53, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(rsqrtps, 0x0f52, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
#undef ALT
#undef DEF_ASM_OP0

File diff suppressed because it is too large Load Diff

360
i386-link.c Normal file
View File

@ -0,0 +1,360 @@
#ifdef TARGET_DEFS_ONLY
#define EM_TCC_TARGET EM_386
/* relocation type for 32 bit data relocation */
#define R_DATA_32 R_386_32
#define R_DATA_PTR R_386_32
#define R_JMP_SLOT R_386_JMP_SLOT
#define R_GLOB_DAT R_386_GLOB_DAT
#define R_COPY R_386_COPY
#define R_RELATIVE R_386_RELATIVE
#define R_NUM R_386_NUM
#define ELF_START_ADDR 0x08048000
#define ELF_PAGE_SIZE 0x1000
#if defined CONFIG_TCC_PIC
#define PCRELATIVE_DLLPLT 1
#else
#define PCRELATIVE_DLLPLT 0
#endif
#define RELOCATE_DLLPLT 1
#else /* !TARGET_DEFS_ONLY */
#include "tcc.h"
#ifdef NEED_RELOC_TYPE
/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
relocations, returns -1. */
ST_FUNC int code_reloc (int reloc_type)
{
switch (reloc_type) {
case R_386_RELATIVE:
case R_386_16:
case R_386_32:
case R_386_GOTPC:
case R_386_GOTOFF:
case R_386_GOT32:
case R_386_GOT32X:
case R_386_GLOB_DAT:
case R_386_COPY:
case R_386_TLS_GD:
case R_386_TLS_LDM:
case R_386_TLS_LDO_32:
case R_386_TLS_LE:
return 0;
case R_386_PC16:
case R_386_PC32:
case R_386_PLT32:
case R_386_JMP_SLOT:
return 1;
}
return -1;
}
/* Returns an enumerator to describe whether and when the relocation needs a
GOT and/or PLT entry to be created. See tcc.h for a description of the
different values. */
ST_FUNC int gotplt_entry_type (int reloc_type)
{
switch (reloc_type) {
case R_386_RELATIVE:
case R_386_16:
case R_386_GLOB_DAT:
case R_386_JMP_SLOT:
case R_386_COPY:
return NO_GOTPLT_ENTRY;
case R_386_32:
/* This relocations shouldn't normally need GOT or PLT
slots if it weren't for simplicity in the code generator.
See our caller for comments. */
return AUTO_GOTPLT_ENTRY;
case R_386_PC16:
case R_386_PC32:
return AUTO_GOTPLT_ENTRY;
case R_386_GOTPC:
case R_386_GOTOFF:
return BUILD_GOT_ONLY;
case R_386_GOT32:
case R_386_GOT32X:
case R_386_PLT32:
case R_386_TLS_GD:
case R_386_TLS_LDM:
case R_386_TLS_LDO_32:
case R_386_TLS_LE:
return ALWAYS_GOTPLT_ENTRY;
}
return -1;
}
#ifdef NEED_BUILD_GOT
ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
{
Section *plt = s1->plt;
uint8_t *p;
int modrm;
unsigned plt_offset, relofs;
/* on i386 if we build a DLL, we add a %ebx offset */
if (s1->output_type & TCC_OUTPUT_DYN)
modrm = 0xa3;
else
modrm = 0x25;
/* empty PLT: create PLT0 entry that pushes the library identifier
(GOT + PTR_SIZE) and jumps to ld.so resolution routine
(GOT + 2 * PTR_SIZE) */
if (plt->data_offset == 0) {
p = section_ptr_add(plt, 16);
p[0] = 0xff; /* pushl got + PTR_SIZE */
p[1] = modrm + 0x10;
write32le(p + 2, PTR_SIZE);
p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
p[7] = modrm;
write32le(p + 8, PTR_SIZE * 2);
}
plt_offset = plt->data_offset;
/* The PLT slot refers to the relocation entry it needs via offset.
The reloc entry is created below, so its offset is the current
data_offset */
relofs = s1->plt->reloc ? s1->plt->reloc->data_offset : 0;
/* Jump to GOT entry where ld.so initially put the address of ip + 4 */
p = section_ptr_add(plt, 16);
p[0] = 0xff; /* jmp *(got + x) */
p[1] = modrm;
write32le(p + 2, got_offset);
p[6] = 0x68; /* push $xxx */
write32le(p + 7, relofs - sizeof (ElfW_Rel));
p[11] = 0xe9; /* jmp plt_start */
write32le(p + 12, -(plt->data_offset));
return plt_offset;
}
/* relocate the PLT: compute addresses and offsets in the PLT now that final
address for PLT and GOT are known (see fill_program_header) */
ST_FUNC void relocate_plt(TCCState *s1)
{
uint8_t *p, *p_end;
if (!s1->plt)
return;
p = s1->plt->data;
p_end = p + s1->plt->data_offset;
if (!(s1->output_type & TCC_OUTPUT_DYN) && p < p_end) {
add32le(p + 2, s1->got->sh_addr);
add32le(p + 8, s1->got->sh_addr);
p += 16;
while (p < p_end) {
add32le(p + 2, s1->got->sh_addr);
p += 16;
}
}
if (s1->plt->reloc) {
ElfW_Rel *rel;
int x = s1->plt->sh_addr + 16 + 6;
p = s1->got->data;
for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {
write32le(p + rel->r_offset, x);
x += 16;
}
}
}
#endif
#endif
ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
{
int sym_index, esym_index;
sym_index = ELFW(R_SYM)(rel->r_info);
switch (type) {
case R_386_32:
if (s1->output_type & TCC_OUTPUT_DYN) {
esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
qrel->r_offset = rel->r_offset;
if (esym_index) {
qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
qrel++;
return;
} else {
qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
qrel++;
}
}
add32le(ptr, val);
return;
case R_386_PC32:
if (s1->output_type == TCC_OUTPUT_DLL) {
/* DLL relocation */
esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
if (esym_index) {
qrel->r_offset = rel->r_offset;
qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
qrel++;
return;
}
}
add32le(ptr, val - addr);
return;
case R_386_PLT32:
add32le(ptr, val - addr);
return;
case R_386_GLOB_DAT:
case R_386_JMP_SLOT:
write32le(ptr, val);
return;
case R_386_GOTPC:
add32le(ptr, s1->got->sh_addr - addr);
return;
case R_386_GOTOFF:
add32le(ptr, val - s1->got->sh_addr);
return;
case R_386_GOT32:
case R_386_GOT32X:
/* we load the got offset */
add32le(ptr, get_sym_attr(s1, sym_index, 0)->got_offset);
return;
case R_386_16:
if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
output_file:
tcc_error_noabort("can only produce 16-bit binary files");
}
write16le(ptr, read16le(ptr) + val);
return;
case R_386_PC16:
if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)
goto output_file;
write16le(ptr, read16le(ptr) + val - addr);
return;
case R_386_RELATIVE:
#ifdef TCC_TARGET_PE
add32le(ptr, val - s1->pe_imagebase);
#endif
/* do nothing */
return;
case R_386_COPY:
/* This relocation must copy initialized data from the library
to the program .bss segment. Currently made like for ARM
(to remove noise of default case). Is this true?
*/
return;
case R_386_TLS_GD:
{
static const unsigned char expect[] = {
/* lea 0(,%ebx,1),%eax */
0x8d, 0x04, 0x1d, 0x00, 0x00, 0x00, 0x00,
/* call __tls_get_addr@PLT */
0xe8, 0xfc, 0xff, 0xff, 0xff };
static const unsigned char replace[] = {
/* mov %gs:0,%eax */
0x65, 0xa1, 0x00, 0x00, 0x00, 0x00,
/* sub 0,%eax */
0x81, 0xe8, 0x00, 0x00, 0x00, 0x00 };
if (memcmp (ptr-3, expect, sizeof(expect)) == 0) {
ElfW(Sym) *sym;
Section *sec;
int32_t x;
memcpy(ptr-3, replace, sizeof(replace));
rel[1].r_info = ELFW(R_INFO)(0, R_386_NONE);
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
sec = s1->sections[sym->st_shndx];
x = sym->st_value - sec->sh_addr - sec->data_offset;
add32le(ptr + 5, -x);
}
else
tcc_error_noabort("unexpected R_386_TLS_GD pattern");
}
return;
case R_386_TLS_LDM:
{
static const unsigned char expect[] = {
/* lea 0(%ebx),%eax */
0x8d, 0x83, 0x00, 0x00, 0x00, 0x00,
/* call __tls_get_addr@PLT */
0xe8, 0xfc, 0xff, 0xff, 0xff };
static const unsigned char replace[] = {
/* mov %gs:0,%eax */
0x65, 0xa1, 0x00, 0x00, 0x00, 0x00,
/* nop */
0x90,
/* lea 0(%esi,%eiz,1),%esi */
0x8d, 0x74, 0x26, 0x00 };
if (memcmp (ptr-2, expect, sizeof(expect)) == 0) {
memcpy(ptr-2, replace, sizeof(replace));
rel[1].r_info = ELFW(R_INFO)(0, R_386_NONE);
}
else
tcc_error_noabort("unexpected R_386_TLS_LDM pattern");
}
return;
case R_386_TLS_LDO_32:
{
ElfW(Sym) *sym;
Section *sec;
int32_t x;
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
sec = s1->sections[sym->st_shndx];
x = val - sec->sh_addr - sec->data_offset;
add32le(ptr, x);
}
return;
case R_386_TLS_LE:
{
ElfW(Sym) *sym;
Section *sec;
int32_t x;
addr_t tls_start = 0, tls_end = 0, tls_align = 1;
int i;
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
sec = s1->sections[sym->st_shndx];
for (i = 1; i < s1->nb_sections; i++) {
Section *s = s1->sections[i];
if (s->sh_flags & SHF_TLS && s->sh_size) {
if (!tls_start || s->sh_addr < tls_start)
tls_start = s->sh_addr;
if (s->sh_addr + s->sh_size > tls_end)
tls_end = s->sh_addr + s->sh_size;
if (s->sh_addralign > tls_align)
tls_align = s->sh_addralign;
}
}
if (tls_end > tls_start) {
addr_t tls_size = tls_end - tls_start;
addr_t aligned_size = (tls_size + tls_align - 1) & ~(tls_align - 1);
x = val - (tls_start + aligned_size);
} else {
x = val - sec->sh_addr - sec->data_offset;
}
add32le(ptr, x);
}
return;
case R_386_NONE:
return;
default:
fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n",
type, (unsigned)addr, ptr, (unsigned)val);
return;
}
}
#endif /* !TARGET_DEFS_ONLY */

332
i386-tok.h Normal file
View File

@ -0,0 +1,332 @@
/* ------------------------------------------------------------------ */
/* WARNING: relative order of tokens is important. */
#define DEF_BWL(x) \
DEF(TOK_ASM_ ## x ## b, #x "b") \
DEF(TOK_ASM_ ## x ## w, #x "w") \
DEF(TOK_ASM_ ## x ## l, #x "l") \
DEF(TOK_ASM_ ## x, #x)
#define DEF_WL(x) \
DEF(TOK_ASM_ ## x ## w, #x "w") \
DEF(TOK_ASM_ ## x ## l, #x "l") \
DEF(TOK_ASM_ ## x, #x)
#ifdef TCC_TARGET_X86_64
# define DEF_BWLQ(x) \
DEF(TOK_ASM_ ## x ## b, #x "b") \
DEF(TOK_ASM_ ## x ## w, #x "w") \
DEF(TOK_ASM_ ## x ## l, #x "l") \
DEF(TOK_ASM_ ## x ## q, #x "q") \
DEF(TOK_ASM_ ## x, #x)
# define DEF_WLQ(x) \
DEF(TOK_ASM_ ## x ## w, #x "w") \
DEF(TOK_ASM_ ## x ## l, #x "l") \
DEF(TOK_ASM_ ## x ## q, #x "q") \
DEF(TOK_ASM_ ## x, #x)
# define DEF_BWLX DEF_BWLQ
# define DEF_WLX DEF_WLQ
/* number of sizes + 1 */
# define NBWLX 5
#else
# define DEF_BWLX DEF_BWL
# define DEF_WLX DEF_WL
/* number of sizes + 1 */
# define NBWLX 4
#endif
#define DEF_FP1(x) \
DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
#define DEF_FP(x) \
DEF(TOK_ASM_ ## f ## x, "f" #x ) \
DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
DEF_FP1(x)
#define DEF_ASMTEST(x,suffix) \
DEF_ASM(x ## o ## suffix) \
DEF_ASM(x ## no ## suffix) \
DEF_ASM(x ## b ## suffix) \
DEF_ASM(x ## c ## suffix) \
DEF_ASM(x ## nae ## suffix) \
DEF_ASM(x ## nb ## suffix) \
DEF_ASM(x ## nc ## suffix) \
DEF_ASM(x ## ae ## suffix) \
DEF_ASM(x ## e ## suffix) \
DEF_ASM(x ## z ## suffix) \
DEF_ASM(x ## ne ## suffix) \
DEF_ASM(x ## nz ## suffix) \
DEF_ASM(x ## be ## suffix) \
DEF_ASM(x ## na ## suffix) \
DEF_ASM(x ## nbe ## suffix) \
DEF_ASM(x ## a ## suffix) \
DEF_ASM(x ## s ## suffix) \
DEF_ASM(x ## ns ## suffix) \
DEF_ASM(x ## p ## suffix) \
DEF_ASM(x ## pe ## suffix) \
DEF_ASM(x ## np ## suffix) \
DEF_ASM(x ## po ## suffix) \
DEF_ASM(x ## l ## suffix) \
DEF_ASM(x ## nge ## suffix) \
DEF_ASM(x ## nl ## suffix) \
DEF_ASM(x ## ge ## suffix) \
DEF_ASM(x ## le ## suffix) \
DEF_ASM(x ## ng ## suffix) \
DEF_ASM(x ## nle ## suffix) \
DEF_ASM(x ## g ## suffix)
/* ------------------------------------------------------------------ */
/* register */
DEF_ASM(al)
DEF_ASM(cl)
DEF_ASM(dl)
DEF_ASM(bl)
DEF_ASM(ah)
DEF_ASM(ch)
DEF_ASM(dh)
DEF_ASM(bh)
DEF_ASM(ax)
DEF_ASM(cx)
DEF_ASM(dx)
DEF_ASM(bx)
DEF_ASM(sp)
DEF_ASM(bp)
DEF_ASM(si)
DEF_ASM(di)
DEF_ASM(eax)
DEF_ASM(ecx)
DEF_ASM(edx)
DEF_ASM(ebx)
DEF_ASM(esp)
DEF_ASM(ebp)
DEF_ASM(esi)
DEF_ASM(edi)
#ifdef TCC_TARGET_X86_64
DEF_ASM(rax)
DEF_ASM(rcx)
DEF_ASM(rdx)
DEF_ASM(rbx)
DEF_ASM(rsp)
DEF_ASM(rbp)
DEF_ASM(rsi)
DEF_ASM(rdi)
#endif
DEF_ASM(mm0)
DEF_ASM(mm1)
DEF_ASM(mm2)
DEF_ASM(mm3)
DEF_ASM(mm4)
DEF_ASM(mm5)
DEF_ASM(mm6)
DEF_ASM(mm7)
DEF_ASM(xmm0)
DEF_ASM(xmm1)
DEF_ASM(xmm2)
DEF_ASM(xmm3)
DEF_ASM(xmm4)
DEF_ASM(xmm5)
DEF_ASM(xmm6)
DEF_ASM(xmm7)
DEF_ASM(cr0)
DEF_ASM(cr1)
DEF_ASM(cr2)
DEF_ASM(cr3)
DEF_ASM(cr4)
DEF_ASM(cr5)
DEF_ASM(cr6)
DEF_ASM(cr7)
DEF_ASM(tr0)
DEF_ASM(tr1)
DEF_ASM(tr2)
DEF_ASM(tr3)
DEF_ASM(tr4)
DEF_ASM(tr5)
DEF_ASM(tr6)
DEF_ASM(tr7)
DEF_ASM(db0)
DEF_ASM(db1)
DEF_ASM(db2)
DEF_ASM(db3)
DEF_ASM(db4)
DEF_ASM(db5)
DEF_ASM(db6)
DEF_ASM(db7)
DEF_ASM(dr0)
DEF_ASM(dr1)
DEF_ASM(dr2)
DEF_ASM(dr3)
DEF_ASM(dr4)
DEF_ASM(dr5)
DEF_ASM(dr6)
DEF_ASM(dr7)
DEF_ASM(es)
DEF_ASM(cs)
DEF_ASM(ss)
DEF_ASM(ds)
DEF_ASM(fs)
DEF_ASM(gs)
DEF_ASM(st)
DEF_ASM(rip)
#ifdef TCC_TARGET_X86_64
/* The four low parts of sp/bp/si/di that exist only on
x86-64 (encoding aliased to ah,ch,dh,dh when not using REX). */
DEF_ASM(spl)
DEF_ASM(bpl)
DEF_ASM(sil)
DEF_ASM(dil)
#endif
/* generic two operands */
DEF_BWLX(mov)
DEF_BWLX(add)
DEF_BWLX(or)
DEF_BWLX(adc)
DEF_BWLX(sbb)
DEF_BWLX(and)
DEF_BWLX(sub)
DEF_BWLX(xor)
DEF_BWLX(cmp)
/* unary ops */
DEF_BWLX(inc)
DEF_BWLX(dec)
DEF_BWLX(not)
DEF_BWLX(neg)
DEF_BWLX(mul)
DEF_BWLX(imul)
DEF_BWLX(div)
DEF_BWLX(idiv)
DEF_BWLX(xchg)
DEF_BWLX(test)
/* shifts */
DEF_BWLX(rol)
DEF_BWLX(ror)
DEF_BWLX(rcl)
DEF_BWLX(rcr)
DEF_BWLX(shl)
DEF_BWLX(shr)
DEF_BWLX(sar)
DEF_WLX(shld)
DEF_WLX(shrd)
DEF_ASM(pushw)
DEF_ASM(pushl)
#ifdef TCC_TARGET_X86_64
DEF_ASM(pushq)
#endif
DEF_ASM(push)
DEF_ASM(popw)
DEF_ASM(popl)
#ifdef TCC_TARGET_X86_64
DEF_ASM(popq)
#endif
DEF_ASM(pop)
DEF_BWL(in)
DEF_BWL(out)
DEF_WLX(movzb)
DEF_ASM(movzwl)
DEF_ASM(movsbw)
DEF_ASM(movsbl)
DEF_ASM(movswl)
#ifdef TCC_TARGET_X86_64
DEF_ASM(movsbq)
DEF_ASM(movswq)
DEF_ASM(movzwq)
DEF_ASM(movslq)
#endif
DEF_WLX(lea)
DEF_ASM(les)
DEF_ASM(lds)
DEF_ASM(lss)
DEF_ASM(lfs)
DEF_ASM(lgs)
DEF_ASM(call)
DEF_ASM(jmp)
DEF_ASM(lcall)
DEF_ASM(ljmp)
DEF_ASMTEST(j,)
DEF_ASMTEST(set,)
DEF_ASMTEST(set,b)
DEF_ASMTEST(cmov,)
DEF_WLX(bsf)
DEF_WLX(bsr)
DEF_WLX(bt)
DEF_WLX(bts)
DEF_WLX(btr)
DEF_WLX(btc)
DEF_WLX(popcnt)
DEF_WLX(tzcnt)
DEF_WLX(lzcnt)
DEF_WLX(lar)
DEF_WLX(lsl)
/* generic FP ops */
DEF_FP(add)
DEF_FP(mul)
DEF_ASM(fcom)
DEF_ASM(fcom_1) /* non existent op, just to have a regular table */
DEF_FP1(com)
DEF_FP(comp)
DEF_FP(sub)
DEF_FP(subr)
DEF_FP(div)
DEF_FP(divr)
DEF_BWLX(xadd)
DEF_BWLX(cmpxchg)
/* string ops */
DEF_BWLX(cmps)
DEF_BWLX(scmp)
DEF_BWL(ins)
DEF_BWL(outs)
DEF_BWLX(lods)
DEF_BWLX(slod)
DEF_BWLX(movs)
DEF_BWLX(smov)
DEF_BWLX(scas)
DEF_BWLX(ssca)
DEF_BWLX(stos)
DEF_BWLX(ssto)
/* generic asm ops */
#define ALT(x)
#define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
#define DEF_ASM_OP0L(name, opcode, group, instr_type)
#define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
#ifdef TCC_TARGET_X86_64
# include "x86_64-asm.h"
#else
# include "i386-asm.h"
#endif
#define ALT(x)
#define DEF_ASM_OP0(name, opcode)
#define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
#ifdef TCC_TARGET_X86_64
# include "x86_64-asm.h"
#else
# include "i386-asm.h"
#endif

View File

@ -18,6 +18,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#error this code has bit-rotted since 2003
/* number of available registers */
#define NB_REGS 3
@ -41,7 +43,7 @@ enum {
REG_ST2,
};
int reg_classes[NB_REGS] = {
const int reg_classes[NB_REGS] = {
/* ST0 */ RC_ST | RC_ST0,
/* ST1 */ RC_ST | RC_ST1,
/* ST2 */ RC_ST,
@ -53,11 +55,11 @@ int reg_classes[NB_REGS] = {
#define REG_FRET REG_ST0 /* float return register */
/* defined if function parameters must be evaluated in reverse order */
//#define INVERT_FUNC_PARAMS
/* #define INVERT_FUNC_PARAMS */
/* defined if structures are passed as pointers. Otherwise structures
are directly pushed on stack. */
//#define FUNC_STRUCT_PARAM_AS_PTR
/* #define FUNC_STRUCT_PARAM_AS_PTR */
/* pointer size, in bytes */
#define PTR_SIZE 4
@ -193,7 +195,7 @@ static void il_type_to_str(char *buf, int buf_size,
pstrcat(buf, buf_size, tstr);
break;
case VT_STRUCT:
error("structures not handled yet");
tcc_error("structures not handled yet");
break;
case VT_FUNC:
s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
@ -387,7 +389,7 @@ void gfunc_start(GFuncContext *c, int func_call)
void gfunc_param(GFuncContext *c)
{
if ((vtop->t & VT_BTYPE) == VT_STRUCT) {
error("structures passed as value not handled yet");
tcc_error("structures passed as value not handled yet");
} else {
/* simply push on stack */
gv(RC_ST0);
@ -441,6 +443,7 @@ void gfunc_prolog(int t)
/* if the function returns a structure, then add an
implicit pointer parameter */
func_vt = sym->t;
func_var = (sym->c == FUNC_ELLIPSIS);
if ((func_vt & VT_BTYPE) == VT_STRUCT) {
func_vc = addr;
addr++;
@ -449,7 +452,7 @@ void gfunc_prolog(int t)
while ((sym = sym->next) != NULL) {
u = sym->t;
sym_push(sym->v & ~SYM_FIELD, u,
VT_LOCAL | VT_LVAL, addr);
VT_LOCAL | lvalue_type(sym->type.t), addr);
addr++;
}
}
@ -528,19 +531,6 @@ int gtst(int inv, int t)
t = gjmp(t);
gsym(vtop->c.i);
}
} else {
if (is_float(vtop->t)) {
vpushi(0);
gen_op(TOK_NE);
}
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST) {
/* constant jmp optimization */
if ((vtop->c.i != 0) != inv)
t = gjmp(t);
} else {
v = gv(RC_INT);
t = out_opj(IL_OP_BRTRUE - inv, t);
}
}
vtop--;
return t;
@ -612,7 +602,7 @@ void gen_opi(int op)
}
/* generate a floating point operation 'v = t1 op t2' instruction. The
two operands are guaranted to have the same floating point type */
two operands are guaranteed to have the same floating point type */
void gen_opf(int op)
{
/* same as integer */

View File

@ -27,7 +27,7 @@
#define DBL_MAX_10_EXP 308
/* horrible intel long double */
#ifdef __i386__
#if defined __i386__ || defined __x86_64__
#define LDBL_MANT_DIG 64
#define LDBL_DIG 18
@ -38,19 +38,37 @@
#define LDBL_MAX_EXP 16384
#define LDBL_MAX 1.18973149535723176502e+4932L
#define LDBL_MAX_10_EXP 4932
#define DECIMAL_DIG 21
#elif defined __aarch64__ || defined __riscv
/*
* Use values from:
* gcc -dM -E -xc /dev/null | grep LDBL | sed -e "s/__//g"
*/
#define LDBL_MANT_DIG 113
#define LDBL_DIG 33
#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L
#define LDBL_MIN_EXP (-16381)
#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
#define LDBL_MIN_10_EXP (-4931)
#define LDBL_MAX_EXP 16384
#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L
#define LDBL_MAX_10_EXP 4932
#define DECIMAL_DIG 36
#else
/* same as IEEE double */
#define LDBL_MANT_DIG 53
#define LDBL_DIG 15
#define LDBL_EPSILON 2.2204460492503131e-16
#define LDBL_EPSILON 2.2204460492503131e-16L
#define LDBL_MIN_EXP (-1021)
#define LDBL_MIN 2.2250738585072014e-308
#define LDBL_MIN 2.2250738585072014e-308L
#define LDBL_MIN_10_EXP (-307)
#define LDBL_MAX_EXP 1024
#define LDBL_MAX 1.7976931348623157e+308
#define LDBL_MAX 1.7976931348623157e+308L
#define LDBL_MAX_10_EXP 308
#define DECIMAL_DIG 17
#endif

16
include/stdalign.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef _STDALIGN_H
#define _STDALIGN_H
#if __STDC_VERSION__ < 201112L && (defined(__GNUC__) || defined(__TINYC__))
# define _Alignas(t) __attribute__((__aligned__(t)))
# define _Alignof(t) __alignof__(t)
#endif
#define alignas _Alignas
#define alignof _Alignof
#define __alignas_is_defined 1
#define __alignof_is_defined 1
#endif /* _STDALIGN_H */

14
include/stdarg.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _STDARG_H
#define _STDARG_H
typedef __builtin_va_list va_list;
#define va_start __builtin_va_start
#define va_arg __builtin_va_arg
#define va_copy __builtin_va_copy
#define va_end __builtin_va_end
/* fix a buggy dependency on GCC in libio.h */
typedef va_list __gnuc_va_list;
#define _VA_LIST_DEFINED
#endif /* _STDARG_H */

171
include/stdatomic.h Normal file
View File

@ -0,0 +1,171 @@
/* This file is derived from clang's stdatomic.h */
/*===---- stdatomic.h - Standard header for atomic types and operations -----===
*
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
* See https://llvm.org/LICENSE.txt for license information.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
*===-----------------------------------------------------------------------===
*/
#ifndef _STDATOMIC_H
#define _STDATOMIC_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#define __ATOMIC_RELAXED 0
#define __ATOMIC_CONSUME 1
#define __ATOMIC_ACQUIRE 2
#define __ATOMIC_RELEASE 3
#define __ATOMIC_ACQ_REL 4
#define __ATOMIC_SEQ_CST 5
/* Memory ordering */
typedef enum {
memory_order_relaxed = __ATOMIC_RELAXED,
memory_order_consume = __ATOMIC_CONSUME,
memory_order_acquire = __ATOMIC_ACQUIRE,
memory_order_release = __ATOMIC_RELEASE,
memory_order_acq_rel = __ATOMIC_ACQ_REL,
memory_order_seq_cst = __ATOMIC_SEQ_CST,
} memory_order;
/* Atomic typedefs */
typedef _Atomic(_Bool) atomic_bool;
typedef _Atomic(char) atomic_char;
typedef _Atomic(signed char) atomic_schar;
typedef _Atomic(unsigned char) atomic_uchar;
typedef _Atomic(short) atomic_short;
typedef _Atomic(unsigned short) atomic_ushort;
typedef _Atomic(int) atomic_int;
typedef _Atomic(unsigned int) atomic_uint;
typedef _Atomic(long) atomic_long;
typedef _Atomic(unsigned long) atomic_ulong;
typedef _Atomic(long long) atomic_llong;
typedef _Atomic(unsigned long long) atomic_ullong;
typedef _Atomic(uint_least16_t) atomic_char16_t;
typedef _Atomic(uint_least32_t) atomic_char32_t;
typedef _Atomic(wchar_t) atomic_wchar_t;
typedef _Atomic(int_least8_t) atomic_int_least8_t;
typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
typedef _Atomic(int_least16_t) atomic_int_least16_t;
typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
typedef _Atomic(int_least32_t) atomic_int_least32_t;
typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
typedef _Atomic(int_least64_t) atomic_int_least64_t;
typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
typedef _Atomic(intptr_t) atomic_intptr_t;
typedef _Atomic(uintptr_t) atomic_uintptr_t;
typedef _Atomic(size_t) atomic_size_t;
typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t;
typedef _Atomic(intmax_t) atomic_intmax_t;
typedef _Atomic(uintmax_t) atomic_uintmax_t;
/* Atomic flag */
typedef struct {
atomic_bool value;
} atomic_flag;
#define ATOMIC_FLAG_INIT {0}
#define ATOMIC_VAR_INIT(value) (value)
/* Generic routines */
#define atomic_init(object, desired) \
atomic_store_explicit(object, desired, __ATOMIC_RELAXED)
#define __atomic_store_n(ptr, val, order) \
(*(ptr) = (val), __atomic_store((ptr), &(typeof(*(ptr))){val}, (order)))
#define atomic_store_explicit(object, desired, order) \
({ __typeof__ (object) ptr = (object); \
__typeof__ (*ptr) tmp = (desired); \
__atomic_store (ptr, &tmp, (order)); \
})
#define atomic_store(object, desired) \
atomic_store_explicit (object, desired, __ATOMIC_SEQ_CST)
#define __atomic_load_n(ptr, order) \
({ typeof(*(ptr)) __val; \
__atomic_load((ptr), &__val, (order)); \
__val; })
#define atomic_load_explicit(object, order) \
({ __typeof__ (object) ptr = (object); \
__typeof__ ((void)0,*ptr) tmp; \
__atomic_load (ptr, &tmp, (order)); \
tmp; \
})
#define atomic_load(object) atomic_load_explicit (object, __ATOMIC_SEQ_CST)
#define atomic_exchange_explicit(object, desired, order) \
({ __typeof__ (object) ptr = (object); \
__typeof__ (*ptr) val = (desired); \
__typeof__ (*ptr) tmp; \
__atomic_exchange (ptr, &val, &tmp, (order)); \
tmp; \
})
#define atomic_exchange(object, desired) \
atomic_exchange_explicit (object, desired, __ATOMIC_SEQ_CST)
#define __atomic_compare_exchange_n(ptr, expected, desired, weak, success, failure) \
({ typeof(*(ptr)) __desired = (desired); \
__atomic_compare_exchange((ptr), (expected), &__desired, \
(weak), (success), (failure)); })
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
({ __typeof__ (object) ptr = (object); \
__typeof__ (*ptr) tmp = desired; \
__atomic_compare_exchange(ptr, expected, &tmp, 0, success, failure); \
})
#define atomic_compare_exchange_strong(object, expected, desired) \
atomic_compare_exchange_strong_explicit (object, expected, desired, \
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
({ __typeof__ (object) ptr = (object); \
__typeof__ (*ptr) tmp = desired; \
__atomic_compare_exchange(ptr, expected, &tmp, 1, success, failure); \
})
#define atomic_compare_exchange_weak(object, expected, desired) \
atomic_compare_exchange_weak_explicit (object, expected, desired, \
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define atomic_fetch_add(object, operand) \
__atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_add_explicit __atomic_fetch_add
#define atomic_fetch_sub(object, operand) \
__atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_sub_explicit __atomic_fetch_sub
#define atomic_fetch_or(object, operand) \
__atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_or_explicit __atomic_fetch_or
#define atomic_fetch_xor(object, operand) \
__atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_xor_explicit __atomic_fetch_xor
#define atomic_fetch_and(object, operand) \
__atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_and_explicit __atomic_fetch_and
extern void atomic_thread_fence (memory_order);
#define __atomic_thread_fence(order) atomic_thread_fence (order)
extern void atomic_signal_fence (memory_order);
#define __atomic_signal_fence(order) atomic_signal_fence(order)
#define atomic_signal_fence(order) __atomic_signal_fence (order)
extern bool __atomic_is_lock_free(size_t size, void *ptr);
#define atomic_is_lock_free(OBJ) __atomic_is_lock_free (sizeof (*(OBJ)), (OBJ))
extern bool atomic_flag_test_and_set(void *object);
extern bool atomic_flag_test_and_set_explicit(void *object, memory_order order);
extern void atomic_flag_clear(void *object);
extern void atomic_flag_clear_explicit(void *object, memory_order order);
#endif /* _STDATOMIC_H */

View File

@ -6,5 +6,6 @@
#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1
#endif /* _STDBOOL_H */

39
include/stddef.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef _STDDEF_H
#define _STDDEF_H
typedef __SIZE_TYPE__ size_t;
typedef __PTRDIFF_TYPE__ ssize_t;
typedef __WCHAR_TYPE__ wchar_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef __PTRDIFF_TYPE__ intptr_t;
typedef __SIZE_TYPE__ uintptr_t;
#if __STDC_VERSION__ >= 201112L
typedef union { long long __ll; long double __ld; } max_align_t;
#endif
#ifndef NULL
#define NULL ((void*)0)
#endif
#undef offsetof
#define offsetof(type, field) __builtin_offsetof(type, field)
void *alloca(size_t size);
#endif
/* Older glibc require a wint_t from <stddef.h> (when requested
by __need_wint_t, as otherwise stddef.h isn't allowed to
define this type). Note that this must be outside the normal
_STDDEF_H guard, so that it works even when we've included the file
already (without requiring wint_t). Some other libs define _WINT_T
if they've already provided that type, so we can use that as guard.
TCC defines __WINT_TYPE__ for us. */
#if defined (__need_wint_t)
#ifndef _WINT_T
#define _WINT_T
typedef __WINT_TYPE__ wint_t;
#endif
#undef __need_wint_t
#endif

7
include/stdnoreturn.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef _STDNORETURN_H
#define _STDNORETURN_H
/* ISOC11 noreturn */
#define noreturn _Noreturn
#endif /* _STDNORETURN_H */

338
include/tccdefs.h Normal file
View File

@ -0,0 +1,338 @@
/* tccdefs.h
Nothing is defined before this file except target machine, target os
and the few things related to option settings in tccpp.c:tcc_predefs().
This file is either included at runtime as is, or converted and
included as C-strings at compile-time (depending on CONFIG_TCC_PREDEFS).
Note that line indent matters:
- in lines starting at column 1, platform macros are replaced by
corresponding TCC target compile-time macros. See conftest.c for
the list of platform macros supported in lines starting at column 1.
- only lines indented >= 4 are actually included into the executable,
check tccdefs_.h.
*/
#if __SIZEOF_POINTER__ == 4
/* 32bit systems. */
#if defined __OpenBSD__
#define __SIZE_TYPE__ unsigned long
#define __PTRDIFF_TYPE__ long
#else
#define __SIZE_TYPE__ unsigned int
#define __PTRDIFF_TYPE__ int
#endif
#define __ILP32__ 1
#define __INT64_TYPE__ long long
#elif __SIZEOF_LONG__ == 4
/* 64bit Windows. */
#define __SIZE_TYPE__ unsigned long long
#define __PTRDIFF_TYPE__ long long
#define __LLP64__ 1
#define __INT64_TYPE__ long long
#else
/* Other 64bit systems. */
#define __SIZE_TYPE__ unsigned long
#define __PTRDIFF_TYPE__ long
#define __LP64__ 1
# if defined __linux__
#define __INT64_TYPE__ long
# else /* APPLE, BSD */
#define __INT64_TYPE__ long long
# endif
#endif
#define __SIZEOF_INT__ 4
#define __INT_MAX__ 0x7fffffff
#if __SIZEOF_LONG__ == 4
#define __LONG_MAX__ 0x7fffffffL
#else
#define __LONG_MAX__ 0x7fffffffffffffffL
#endif
#define __SIZEOF_LONG_LONG__ 8
#define __LONG_LONG_MAX__ 0x7fffffffffffffffLL
#define __CHAR_BIT__ 8
#define __ORDER_LITTLE_ENDIAN__ 1234
#define __ORDER_BIG_ENDIAN__ 4321
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
#if defined _WIN32
#define __WCHAR_TYPE__ unsigned short
#define __WINT_TYPE__ unsigned short
#elif defined __linux__
#define __WCHAR_TYPE__ int
#define __WINT_TYPE__ unsigned int
#else
#define __WCHAR_TYPE__ int
#define __WINT_TYPE__ int
#endif
#if __STDC_VERSION__ >= 201112L
# define __STDC_NO_ATOMICS__ 1
# define __STDC_NO_COMPLEX__ 1
# define __STDC_NO_THREADS__ 1
#if !defined _WIN32
# define __STDC_UTF_16__ 1
# define __STDC_UTF_32__ 1
#endif
#endif
#if defined _WIN32
#define __declspec(x) __attribute__((x))
#define __cdecl
#elif defined __FreeBSD__
#define __GNUC__ 9
#define __GNUC_MINOR__ 3
#define __GNUC_PATCHLEVEL__ 0
#define __GNUC_STDC_INLINE__ 1
#define __NO_TLS 1
#define __RUNETYPE_INTERNAL 1
# if __SIZEOF_POINTER__ == 8
#define __SIZEOF_SIZE_T__ 8
#define __SIZEOF_PTRDIFF_T__ 8
#else
#define __SIZEOF_SIZE_T__ 4
#define __SIZEOF_PTRDIFF_T__ 4
# endif
#elif defined __FreeBSD_kernel__
#elif defined __NetBSD__
#define __GNUC__ 4
#define __GNUC_MINOR__ 1
#define __GNUC_PATCHLEVEL__ 0
#define _Pragma(x)
#define __ELF__ 1
#if defined __aarch64__
#define _LOCORE /* avoids usage of __asm */
#endif
#elif defined __OpenBSD__
#define __GNUC__ 4
#define _ANSI_LIBRARY 1
#elif defined __APPLE__
/* emulate APPLE-GCC to make libc's headerfiles compile: */
#define __GNUC__ 4 /* darwin emits warning on GCC<4 */
#define __APPLE_CC__ 1 /* for <TargetConditionals.h> */
#define __LITTLE_ENDIAN__ 1
#define _DONT_USE_CTYPE_INLINE_ 1
/* avoids usage of GCC/clang specific builtins in libc-headerfiles: */
#define __FINITE_MATH_ONLY__ 1
#define _FORTIFY_SOURCE 0
//#define __has_builtin(x) 0
#define _Float16 short unsigned int /* fake type just for size & alignment (macOS Sequoia) */
#elif defined __ANDROID__
#define BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD
#else
/* Linux */
#endif
/* Some derived integer types needed to get stdint.h to compile correctly on some platforms */
#ifndef __NetBSD__
#define __UINTPTR_TYPE__ unsigned __PTRDIFF_TYPE__
#define __INTPTR_TYPE__ __PTRDIFF_TYPE__
#endif
#define __INT32_TYPE__ int
#if !defined _WIN32
/* glibc defines. We do not support __USER_NAME_PREFIX__ */
#define __REDIRECT(name, proto, alias) name proto __asm__ (#alias)
#define __REDIRECT_NTH(name, proto, alias) name proto __asm__ (#alias) __THROW
#define __REDIRECT_NTHNL(name, proto, alias) name proto __asm__ (#alias) __THROWNL
#endif
/* not implemented */
#define __PRETTY_FUNCTION__ __FUNCTION__
#define __has_builtin(x) 0
#define __has_feature(x) 0
#define __has_attribute(x) 0
/* C23 Keywords */
#define _Nonnull
#define _Nullable
#define _Nullable_result
#define _Null_unspecified
/* skip __builtin... with -E */
#ifndef __TCC_PP__
#define __builtin_offsetof(type, field) ((__SIZE_TYPE__)&((type*)0)->field)
#define __builtin_extract_return_addr(x) x
#if !defined __linux__ && !defined _WIN32
/* used by math.h */
#define __builtin_huge_val() 1e500
#define __builtin_huge_valf() 1e50f
#define __builtin_huge_vall() 1e5000L
# if defined __APPLE__
#define __builtin_nanf(ignored_string) (0.0F/0.0F)
/* used by floats.h to implement FLT_ROUNDS C99 macro. 1 == to nearest */
#define __builtin_flt_rounds() 1
/* used by _fd_def.h */
#define __builtin_bzero(p, ignored_size) bzero(p, sizeof(*(p)))
# else
#define __builtin_nanf(ignored_string) (0.0F/0.0F)
# endif
#endif
/* GCC's __uint128_t appears in some Linux/OSX header files.
Just make it some type with same size and alignment. */
struct __uint128__ { char x[16]; } __attribute((__aligned__(16)));
#define __int128_t struct __uint128__
#define __uint128_t struct __uint128__
/* __builtin_va_list */
#if defined __x86_64__
#if !defined _WIN32
/* GCC compatible definition of va_list. */
/* This should be in sync with the declaration in our lib/va_list.c */
typedef struct {
unsigned gp_offset, fp_offset;
union {
unsigned overflow_offset;
char *overflow_arg_area;
};
char *reg_save_area;
} __builtin_va_list[1];
void *__va_arg(__builtin_va_list ap, int arg_type, int size, int align);
#define __builtin_va_start(ap, last) \
(*(ap) = *(__builtin_va_list)((char*)__builtin_frame_address(0) - 24))
#define __builtin_va_arg(ap, t) \
(*(t *)(__va_arg(ap, __builtin_va_arg_types(t), sizeof(t), __alignof__(t))))
#define __builtin_va_copy(dest, src) (*(dest) = *(src))
#else /* _WIN64 */
typedef char *__builtin_va_list;
#define __builtin_va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \
? **(t **)((ap += 8) - 8) : *(t *)((ap += 8) - 8))
#endif
#elif defined __arm__
typedef char *__builtin_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 __builtin_va_start(ap,last) (ap = ((char *)&(last)) + ((sizeof(last)+3)&~3))
#define __builtin_va_arg(ap,type) (ap = (void *) ((_tcc_align(ap,type)+sizeof(type)+3) \
&~3), *(type *)(ap - ((sizeof(type)+3)&~3)))
#elif defined __aarch64__
#if defined _WIN32
typedef char *__builtin_va_list;
#elif defined __APPLE__
typedef struct {
void *__stack;
} __builtin_va_list;
#else
typedef struct {
void *__stack, *__gr_top, *__vr_top;
int __gr_offs, __vr_offs;
} __builtin_va_list;
#endif
#elif defined __riscv
typedef char *__builtin_va_list;
#define __va_reg_size (__riscv_xlen >> 3)
#define _tcc_align(addr,type) (((unsigned long)addr + __alignof__(type) - 1) \
& -(__alignof__(type)))
#define __builtin_va_arg(ap,type) (*(sizeof(type) > (2*__va_reg_size) ? *(type **)((ap += __va_reg_size) - __va_reg_size) : (ap = (va_list)(_tcc_align(ap,type) + (sizeof(type)+__va_reg_size - 1)& -__va_reg_size), (type *)(ap - ((sizeof(type)+ __va_reg_size - 1)& -__va_reg_size)))))
#else /* __i386__ */
typedef char *__builtin_va_list;
#define __builtin_va_start(ap,last) (ap = ((char *)&(last)) + ((sizeof(last)+3)&~3))
#define __builtin_va_arg(ap,t) (*(t*)((ap+=(sizeof(t)+3)&~3)-((sizeof(t)+3)&~3)))
#endif
#define __builtin_va_end(ap) (void)(ap)
#ifndef __builtin_va_copy
# define __builtin_va_copy(dest, src) (dest) = (src)
#endif
/* TCC BBUILTIN AND BOUNDS ALIASES */
#ifdef __leading_underscore
# define __RENAME(X) __asm__("_"X)
#else
# define __RENAME(X) __asm__(X)
#endif
#ifdef __TCC_BCHECK__
# define __BUILTINBC(ret,name,params) ret __builtin_##name params __RENAME("__bound_"#name);
# define __BOUND(ret,name,params) ret name params __RENAME("__bound_"#name);
#else
# define __BUILTINBC(ret,name,params) ret __builtin_##name params __RENAME(#name);
# define __BOUND(ret,name,params)
#endif
#ifdef _WIN32
#define __BOTH __BOUND
#define __BUILTIN(ret,name,params)
#else
#define __BOTH(ret,name,params) __BUILTINBC(ret,name,params)__BOUND(ret,name,params)
#define __BUILTIN(ret,name,params) ret __builtin_##name params __RENAME(#name);
#endif
__BOTH(void*, memcpy, (void *, const void*, __SIZE_TYPE__))
__BOTH(void*, memmove, (void *, const void*, __SIZE_TYPE__))
__BOTH(void*, memset, (void *, int, __SIZE_TYPE__))
__BOTH(int, memcmp, (const void *, const void*, __SIZE_TYPE__))
__BOTH(__SIZE_TYPE__, strlen, (const char *))
__BOTH(char*, strcpy, (char *, const char *))
__BOTH(char*, strncpy, (char *, const char*, __SIZE_TYPE__))
__BOTH(int, strcmp, (const char*, const char*))
__BOTH(int, strncmp, (const char*, const char*, __SIZE_TYPE__))
__BOTH(char*, strcat, (char*, const char*))
__BOTH(char*, strncat, (char*, const char*, __SIZE_TYPE__))
__BOTH(char*, strchr, (const char*, int))
__BOTH(char*, strrchr, (const char*, int))
__BOTH(char*, strdup, (const char*))
#if defined __ARM_EABI__
__BOUND(void*,__aeabi_memcpy,(void*,const void*,__SIZE_TYPE__))
__BOUND(void*,__aeabi_memmove,(void*,const void*,__SIZE_TYPE__))
__BOUND(void*,__aeabi_memmove4,(void*,const void*,__SIZE_TYPE__))
__BOUND(void*,__aeabi_memmove8,(void*,const void*,__SIZE_TYPE__))
__BOUND(void*,__aeabi_memset,(void*,int,__SIZE_TYPE__))
#endif
#if defined __linux__ || defined __APPLE__ // HAVE MALLOC_REDIR
#define __MAYBE_REDIR __BUILTIN
#else
#define __MAYBE_REDIR __BOTH
#endif
__MAYBE_REDIR(void*, malloc, (__SIZE_TYPE__))
__MAYBE_REDIR(void*, realloc, (void *, __SIZE_TYPE__))
__MAYBE_REDIR(void*, calloc, (__SIZE_TYPE__, __SIZE_TYPE__))
__MAYBE_REDIR(void*, memalign, (__SIZE_TYPE__, __SIZE_TYPE__))
__MAYBE_REDIR(void, free, (void*))
__BOTH(void*, alloca, (__SIZE_TYPE__))
void *alloca(__SIZE_TYPE__);
__BUILTIN(void, abort, (void))
__BOUND(void, longjmp, ())
#if !defined _WIN32
__BOUND(void*, mmap, ())
__BOUND(int, munmap, ())
#endif
#undef __BUILTINBC
#undef __BUILTIN
#undef __BOUND
#undef __BOTH
#undef __MAYBE_REDIR
#undef __RENAME
#define __BUILTIN_EXTERN(name,u) \
int __builtin_##name(u int); \
int __builtin_##name##l(u long); \
int __builtin_##name##ll(u long long);
__BUILTIN_EXTERN(ffs,)
__BUILTIN_EXTERN(clz, unsigned)
__BUILTIN_EXTERN(ctz, unsigned)
__BUILTIN_EXTERN(clrsb,)
__BUILTIN_EXTERN(popcount, unsigned)
__BUILTIN_EXTERN(parity, unsigned)
#undef __BUILTIN_EXTERN
#endif /* ndef __TCC_PP__ */

89
include/tgmath.h Normal file
View File

@ -0,0 +1,89 @@
/*
* ISO C Standard: 7.22 Type-generic math <tgmath.h>
*/
#ifndef _TGMATH_H
#define _TGMATH_H
#include <math.h>
#ifndef __cplusplus
#define __tgmath_real(x, F) \
_Generic ((x), float: F##f, long double: F##l, default: F)(x)
#define __tgmath_real_2_1(x, y, F) \
_Generic ((x), float: F##f, long double: F##l, default: F)(x, y)
#define __tgmath_real_2(x, y, F) \
_Generic ((x)+(y), float: F##f, long double: F##l, default: F)(x, y)
#define __tgmath_real_3_2(x, y, z, F) \
_Generic ((x)+(y), float: F##f, long double: F##l, default: F)(x, y, z)
#define __tgmath_real_3(x, y, z, F) \
_Generic ((x)+(y)+(z), float: F##f, long double: F##l, default: F)(x, y, z)
/* Functions defined in both <math.h> and <complex.h> (7.22p4) */
#define acos(z) __tgmath_real(z, acos)
#define asin(z) __tgmath_real(z, asin)
#define atan(z) __tgmath_real(z, atan)
#define acosh(z) __tgmath_real(z, acosh)
#define asinh(z) __tgmath_real(z, asinh)
#define atanh(z) __tgmath_real(z, atanh)
#define cos(z) __tgmath_real(z, cos)
#define sin(z) __tgmath_real(z, sin)
#define tan(z) __tgmath_real(z, tan)
#define cosh(z) __tgmath_real(z, cosh)
#define sinh(z) __tgmath_real(z, sinh)
#define tanh(z) __tgmath_real(z, tanh)
#define exp(z) __tgmath_real(z, exp)
#define log(z) __tgmath_real(z, log)
#define pow(z1,z2) __tgmath_real_2(z1, z2, pow)
#define sqrt(z) __tgmath_real(z, sqrt)
#define fabs(z) __tgmath_real(z, fabs)
/* Functions defined in <math.h> only (7.22p5) */
#define atan2(x,y) __tgmath_real_2(x, y, atan2)
#define cbrt(x) __tgmath_real(x, cbrt)
#define ceil(x) __tgmath_real(x, ceil)
#define copysign(x,y) __tgmath_real_2(x, y, copysign)
#define erf(x) __tgmath_real(x, erf)
#define erfc(x) __tgmath_real(x, erfc)
#define exp2(x) __tgmath_real(x, exp2)
#define expm1(x) __tgmath_real(x, expm1)
#define fdim(x,y) __tgmath_real_2(x, y, fdim)
#define floor(x) __tgmath_real(x, floor)
#define fma(x,y,z) __tgmath_real_3(x, y, z, fma)
#define fmax(x,y) __tgmath_real_2(x, y, fmax)
#define fmin(x,y) __tgmath_real_2(x, y, fmin)
#define fmod(x,y) __tgmath_real_2(x, y, fmod)
#define frexp(x,y) __tgmath_real_2_1(x, y, frexp)
#define hypot(x,y) __tgmath_real_2(x, y, hypot)
#define ilogb(x) __tgmath_real(x, ilogb)
#define ldexp(x,y) __tgmath_real_2_1(x, y, ldexp)
#define lgamma(x) __tgmath_real(x, lgamma)
#define llrint(x) __tgmath_real(x, llrint)
#define llround(x) __tgmath_real(x, llround)
#define log10(x) __tgmath_real(x, log10)
#define log1p(x) __tgmath_real(x, log1p)
#define log2(x) __tgmath_real(x, log2)
#define logb(x) __tgmath_real(x, logb)
#define lrint(x) __tgmath_real(x, lrint)
#define lround(x) __tgmath_real(x, lround)
#define nearbyint(x) __tgmath_real(x, nearbyint)
#define nextafter(x,y) __tgmath_real_2(x, y, nextafter)
#define nexttoward(x,y) __tgmath_real_2(x, y, nexttoward)
#define remainder(x,y) __tgmath_real_2(x, y, remainder)
#define remquo(x,y,z) __tgmath_real_3_2(x, y, z, remquo)
#define rint(x) __tgmath_real(x, rint)
#define round(x) __tgmath_real(x, round)
#define scalbln(x,y) __tgmath_real_2_1(x, y, scalbln)
#define scalbn(x,y) __tgmath_real_2_1(x, y, scalbn)
#define tgamma(x) __tgmath_real(x, tgamma)
#define trunc(x) __tgmath_real(x, trunc)
/* Functions defined in <complex.h> only (7.22p6)
#define carg(z) __tgmath_cplx_only(z, carg)
#define cimag(z) __tgmath_cplx_only(z, cimag)
#define conj(z) __tgmath_cplx_only(z, conj)
#define cproj(z) __tgmath_cplx_only(z, cproj)
#define creal(z) __tgmath_cplx_only(z, creal)
*/
#endif /* __cplusplus */
#endif /* _TGMATH_H */

12
include/varargs.h Normal file
View File

@ -0,0 +1,12 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the w64 mingw-runtime package.
* No warranty is given; refer to the file DISCLAIMER within this package.
*/
#ifndef _VARARGS_H
#define _VARARGS_H
#error "TinyCC no longer implements <varargs.h>."
#error "Revise your code to use <stdarg.h>."
#endif

106
lib/Makefile Normal file
View File

@ -0,0 +1,106 @@
#
# Tiny C Compiler Makefile for libtcc1.a
#
TOP = ..
include $(TOP)/Makefile
VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib
T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
XCFG = $(or $(findstring -win,$T),-unx)
S = $(if $(findstring yes,$(SILENT)),@$(info * $@))
TCC = $(TOP)/$(X)tcc$(EXESUF)
XTCC ?= $(TOP)/$(X)tcc$(EXESUF)
XCC = $(XTCC)
XAR = $(XTCC) -ar
XFLAGS-unx = -B$(TOPSRC)
XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include
XFLAGS = $(XFLAGS$(XCFG))
BFLAGS = -bt
# in order to use gcc, type: make <target>-libtcc1-usegcc=yes
arm-libtcc1-usegcc ?= no
# This makes bounds checking 40%..60% faster.
#x86_64-libtcc1-usegcc=yes
#i386-libtcc1-usegcc=yes
ifeq "$($(T)-libtcc1-usegcc)" "yes"
XCC = $(CC)
XAR = $(AR)
XFLAGS = $(CFLAGS) -fPIC -fno-omit-frame-pointer -Wno-unused-function -Wno-unused-variable
BFLAGS = $(if $(CONFIG_dwarf),-gdwarf,-gstabs)
endif
XFLAGS += -I$(TOP)
I386_O = libtcc1.o $(COMMON_O)
X86_64_O = libtcc1.o $(COMMON_O)
ARM_O = libtcc1.o armeabi.o armflush.o $(COMMON_O)
ARM64_O = lib-arm64.o $(COMMON_O)
RISCV64_O = lib-arm64.o $(COMMON_O)
COMMON_O = stdatomic.o atomic.o builtin.o alloca.o alloca-bt.o
WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o winex.o
LIN_O = dsohandle.o
OSX_O =
# backtrace/bcheck/run only for native compiler
Nat = $(if $X,no,)
Cbt = $(Nat)$(subst yes,,$(CONFIG_backtrace))
Cbc = $(Cbt)$(subst yes,,$(CONFIG_bcheck))
$(Nat)COMMON_O += runmain.o tcov.o
$(Cbt)COMMON_O += bt-exe.o bt-log.o
$(Cbt)WIN_O += bt-dll.o
$(Cbc)COMMON_O += bcheck.o
# not in libtcc1.a
EXTRA_O = runmain.o bt-exe.o bt-dll.o bt-log.o bcheck.o
OBJ-i386 = $(I386_O) pic86.o $(LIN_O)
OBJ-x86_64 = $(X86_64_O) va_list.o $(LIN_O)
OBJ-x86_64-osx = $(X86_64_O) va_list.o $(OSX_O)
OBJ-i386-win32 = $(I386_O) chkstk.o $(WIN_O)
OBJ-x86_64-win32 = $(X86_64_O) chkstk.o $(WIN_O)
OBJ-arm64 = $(ARM64_O) armflush.o $(LIN_O)
OBJ-arm64-osx = $(ARM64_O) $(OSX_O)
OBJ-arm64-win32 = $(ARM64_O) chkstk.o $(WIN_O)
OBJ-arm = $(ARM_O) $(LIN_O)
OBJ-arm-fpa = $(OBJ-arm)
OBJ-arm-fpa-ld = $(OBJ-arm)
OBJ-arm-vfp = $(OBJ-arm)
OBJ-arm-eabi = $(OBJ-arm)
OBJ-arm-eabihf = $(OBJ-arm)
OBJ-arm-wince = $(ARM_O) $(WIN_O)
OBJ-riscv64 = $(RISCV64_O) lib-riscv.o $(LIN_O)
OBJ-extra = $(filter $(EXTRA_O),$(OBJ-$T))
OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T)))
ALL = $(addprefix $(TOP)/,$(X)libtcc1.a $(OBJ-extra))
all: $(ALL)
$(TOP)/$(X)libtcc1.a : $(OBJ-libtcc1) $(TCC)
$S$(XAR) rcs $@ $(OBJ-libtcc1)
$(X)%.o : %.c $(TCC)
$S$(XCC) -c $< -o $@ $(XFLAGS)
$(X)%.o : %.S $(TCC)
$S$(XCC) -c $< -o $@ $(XFLAGS)
$(TOP)/%.o : %.c $(TCC)
$S$(XCC) -c $< -o $@ $(XFLAGS)
$(TOP)/bcheck.o : XFLAGS += $(BFLAGS)
$(X)crt1w.o : crt1.c
$(X)wincrt1w.o : wincrt1.c
# don't try to make it
$(TCC) : ;
clean :
rm -f *.o $(addprefix $(TOP)/,*libtcc1.a $(EXTRA_O))

200
lib/alloca-bt.S Normal file
View File

@ -0,0 +1,200 @@
/* ---------------------------------------------- */
/* alloca-bt.S */
#ifdef __leading_underscore
# define _(s) _##s
#else
# define _(s) s
#endif
/* ---------------------------------------------- */
#if defined __i386__
.globl _(__bound_alloca)
_(__bound_alloca):
pop %edx
pop %eax
mov %eax, %ecx
test %eax,%eax
jz p6
add $3 + 1,%eax
and $-4,%eax
#ifdef _WIN32
p4:
cmp $4096,%eax
jb p5
test %eax,-4096(%esp)
sub $4096,%esp
sub $4096,%eax
jmp p4
p5:
#endif
sub %eax,%esp
mov %esp,%eax
push %edx
push %eax
push %ecx
push %eax
call _(__bound_new_region)
add $8, %esp
pop %eax
pop %edx
p6:
push %edx
push %edx
ret
/* ---------------------------------------------- */
#elif defined __x86_64__
.globl _(__bound_alloca)
_(__bound_alloca):
#ifdef _WIN32
inc %rcx # add one extra to separate regions
jmp _(alloca)
.globl _(__bound_alloca_nr)
_(__bound_alloca_nr):
dec %rcx
push %rax
mov %rcx,%rdx
mov %rax,%rcx
sub $32,%rsp
call _(__bound_new_region)
add $32,%rsp
pop %rax
ret
#else
pop %rdx
mov %rdi,%rax
and %eax,%eax
jz p3
mov %rax,%rsi # size, a second parm to the __bound_new_region
add $15 + 1,%rax # add one extra to separate regions
and $-16,%rax
sub %rax,%rsp
mov %rsp,%rdi # pointer, a first parm to the __bound_new_region
mov %rsp,%rax
push %rdx
push %rax
call _(__bound_new_region)
pop %rax
pop %rdx
p3:
push %rdx
ret
#endif
/* ---------------------------------------------- */
#elif defined __arm__
.globl _(__bound_alloca)
_(__bound_alloca):
mov r1, r0
add r0, r0, #1
rsb sp, r0, sp
bic sp, sp, #7
mov r0, sp
push { lr }
bl _(__bound_new_region)
pop { lr }
mov r0, sp
mov pc, lr
/* ---------------------------------------------- */
#elif defined __aarch64__ || defined __arm64__
.globl _(__bound_alloca)
_(__bound_alloca):
#ifdef __TINYC__
.int 0xaa0003e1
.int 0x91004000
.int 0x927cec00
#ifdef _WIN32
.int 0xb4000160
.int 0xd2820002
.int 0xeb02001f
.int 0x540000c3
.int 0xcb2263e3
.int 0xf940007f
.int 0xcb2263ff
.int 0xcb020000
.int 0x17fffffa
.int 0xb4000040
#endif
.int 0xcb2063ff
.int 0x910003e0
.int 0xa9bf7bfd
.reloc ., R_AARCH64_CALL26, _(__bound_new_region)
.int 0x94000000
.int 0xa8c17bfd
.int 0x910003e0
.int 0xd65f03c0
#else
mov x1, x0
add x0, x0, #16 // Round up to 16-byte boundary
and x0, x0, #-16 // Ensure 16-byte alignment
#ifdef _WIN32
cbz x0, p100 // If size is 0, skip to return
// Windows requires page-wise allocation with stack probing
mov x2, #4096 // Page size = 4096 bytes
p101:
cmp x0, x2 // Compare remaining size with page size
b.lo p102 // If less than page, jump to remainder
// Probe first, then allocate
sub x3, sp, x2 // Calculate guard page address (sp - 4096)
ldr xzr, [x3] // Touch guard page FIRST
sub sp, sp, x2 // THEN allocate the page
sub x0, x0, x2 // Decrement remaining size
b p101 // Continue loop
p102:
// Allocate remaining bytes (less than one page)
cbz x0, p100 // If no remaining bytes, skip
sub sp, sp, x0 // Allocate remaining space
#else
// Non-Windows: simple one-time allocation
sub sp, sp, x0 // Allocate space on stack
#endif
p100:
mov x0, sp // Return allocated address
stp x29, x30, [sp, #-16]!
bl _(__bound_new_region)
ldp x29, x30, [sp], #16
mov x0, sp // Return allocated address
ret // Return to caller
#endif
/* ---------------------------------------------- */
#elif defined __riscv
.globl _(__bound_alloca)
_(__bound_alloca):
mv a1, a0
sub sp, sp, a0
addi sp, sp, -16
andi sp, sp, -16
add a0, sp, zero
addi sp,sp,-16
sd s0,0(sp)
sd ra,8(sp)
jal _(__bound_new_region)
ld s0,0(sp)
ld ra,8(sp)
addi sp,sp,16
add a0, sp, zero
ret
/* ---------------------------------------------- */
#endif

148
lib/alloca.S Normal file
View File

@ -0,0 +1,148 @@
/* ---------------------------------------------- */
/* alloca.S */
#ifdef __leading_underscore
# define _(s) _##s
#else
# define _(s) s
#endif
/* ---------------------------------------------- */
#if defined __i386__
.globl _(alloca), _(__alloca)
_(alloca):
_(__alloca):
pop %edx
pop %eax
add $3,%eax
and $-4,%eax
jz p3
#ifdef _WIN32
p1:
cmp $4096,%eax
jb p2
test %eax,-4096(%esp)
sub $4096,%esp
sub $4096,%eax
jmp p1
p2:
#endif
sub %eax,%esp
mov %esp,%eax
p3:
push %edx
push %edx
ret
/* ---------------------------------------------- */
#elif defined __x86_64__
.globl _(alloca)
_(alloca):
pop %rdx
#ifdef _WIN32
mov %rcx,%rax
#else
mov %rdi,%rax
#endif
add $15,%rax
and $-16,%rax
jz p3
#ifdef _WIN32
p1:
cmp $4096,%rax
jb p2
test %rax,-4096(%rsp)
sub $4096,%rsp
sub $4096,%rax
jmp p1
p2:
#endif
sub %rax,%rsp
mov %rsp,%rax
p3:
push %rdx
ret
/* ---------------------------------------------- */
#elif defined __arm__
.globl _(alloca)
_(alloca):
rsb sp, r0, sp
bic sp, sp, #7
mov r0, sp
mov pc, lr
/* ---------------------------------------------- */
#elif defined __aarch64__ || defined __arm64__
.globl _(alloca)
_(alloca):
#ifdef __TINYC__
.int 0x91003c00
.int 0x927cec00
#ifdef _WIN32
.int 0xb4000160
.int 0xd2820001
.int 0xeb01001f
.int 0x540000c3
.int 0xcb2163e2
.int 0xf940005f
.int 0xcb2163ff
.int 0xcb010000
.int 0x17fffffa
.int 0xb4000040
#endif
.int 0xcb2063ff
.int 0x910003e0
.int 0xd65f03c0
#else
add x0, x0, #15 // Round up to 16-byte boundary
and x0, x0, #-16 // Ensure 16-byte alignment
#ifdef _WIN32
cbz x0, p100 // If size is 0, skip to return
// Windows requires page-wise allocation with stack probing
mov x1, #4096 // Page size = 4096 bytes
p101:
cmp x0, x1 // Compare remaining size with page size
b.lo p102 // If less than page, jump to remainder
// Probe first, then allocate
sub x2, sp, x1 // Calculate guard page address (sp - 4096)
ldr xzr, [x2] // Touch guard page FIRST
sub sp, sp, x1 // THEN allocate the page
sub x0, x0, x1 // Decrement remaining size
b p101 // Continue loop
p102:
// Allocate remaining bytes (less than one page)
cbz x0, p100 // If no remaining bytes, skip
sub sp, sp, x0 // Allocate remaining space
#else
// Non-Windows: simple one-time allocation
sub sp, sp, x0 // Allocate space on stack
#endif
p100:
mov x0, sp // Return allocated address
ret // Return to caller
#endif
/* ---------------------------------------------- */
#elif defined __riscv
.globl _(alloca)
_(alloca):
sub sp, sp, a0
addi sp, sp, -15
andi sp, sp, -16
add a0, sp, zero
ret
#endif

642
lib/armeabi.c Normal file
View File

@ -0,0 +1,642 @@
/* TCC ARM runtime EABI
Copyright (C) 2013 Thomas Preud'homme
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.*/
#ifdef __TINYC__
#define INT_MIN (-2147483647 - 1)
#define INT_MAX 2147483647
#define UINT_MAX 0xffffffff
#define LONG_MIN (-2147483647L - 1)
#define LONG_MAX 2147483647L
#define ULONG_MAX 0xffffffffUL
#define LLONG_MAX 9223372036854775807LL
#define LLONG_MIN (-9223372036854775807LL - 1)
#define ULLONG_MAX 0xffffffffffffffffULL
#else
#include <limits.h>
#endif
/* We rely on the little endianness and EABI calling convention for this to
work */
typedef struct double_unsigned_struct {
unsigned low;
unsigned high;
} double_unsigned_struct;
typedef struct unsigned_int_struct {
unsigned low;
int high;
} unsigned_int_struct;
#define REGS_RETURN(name, type) \
static void name ## _return(type ret) {}
/* Float helper functions */
#define FLOAT_EXP_BITS 8
#define FLOAT_FRAC_BITS 23
#define DOUBLE_EXP_BITS 11
#define DOUBLE_FRAC_BITS 52
#define ONE_EXP(type) ((1 << (type ## _EXP_BITS - 1)) - 1)
REGS_RETURN(unsigned_int_struct, unsigned_int_struct)
REGS_RETURN(double_unsigned_struct, double_unsigned_struct)
/* float -> integer: (sign) 1.fraction x 2^(exponent - exp_for_one) */
/* float to [unsigned] long long conversion */
#define DEFINE__AEABI_F2XLZ(name, with_sign) \
void __aeabi_ ## name(unsigned val) \
{ \
int exp, high_shift, sign; \
double_unsigned_struct ret; \
\
/* compute sign */ \
sign = val >> 31; \
\
/* compute real exponent */ \
exp = val >> FLOAT_FRAC_BITS; \
exp &= (1 << FLOAT_EXP_BITS) - 1; \
exp -= ONE_EXP(FLOAT); \
\
/* undefined behavior if truncated value cannot be represented */ \
if (with_sign) { \
if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \
return; \
} else { \
if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */ \
return; \
} \
\
val &= (1 << FLOAT_FRAC_BITS) - 1; \
if (exp >= 32) { \
ret.high = 1 << (exp - 32); \
if (exp - 32 >= FLOAT_FRAC_BITS) { \
ret.high |= val << (exp - 32 - FLOAT_FRAC_BITS); \
ret.low = 0; \
} else { \
high_shift = FLOAT_FRAC_BITS - (exp - 32); \
ret.high |= val >> high_shift; \
ret.low = val << (32 - high_shift); \
} \
} else { \
ret.high = 0; \
ret.low = 1 << exp; \
if (exp > FLOAT_FRAC_BITS) \
ret.low |= val << (exp - FLOAT_FRAC_BITS); \
else \
ret.low |= val >> (FLOAT_FRAC_BITS - exp); \
} \
\
/* encode negative integer using 2's complement */ \
if (with_sign && sign) { \
ret.low = ~ret.low; \
ret.high = ~ret.high; \
if (ret.low == UINT_MAX) { \
ret.low = 0; \
ret.high++; \
} else \
ret.low++; \
} \
\
double_unsigned_struct_return(ret); \
}
/* float to unsigned long long conversion */
DEFINE__AEABI_F2XLZ(f2ulz, 0)
/* float to long long conversion */
DEFINE__AEABI_F2XLZ(f2lz, 1)
/* double to [unsigned] long long conversion */
#define DEFINE__AEABI_D2XLZ(name, with_sign) \
void __aeabi_ ## name(double_unsigned_struct val) \
{ \
int exp, high_shift, sign; \
double_unsigned_struct ret; \
\
if ((val.high & ~0x80000000) == 0 && val.low == 0) { \
ret.low = ret.high = 0; \
goto _ret_; \
} \
\
/* compute sign */ \
sign = val.high >> 31; \
\
/* compute real exponent */ \
exp = (val.high >> (DOUBLE_FRAC_BITS - 32)); \
exp &= (1 << DOUBLE_EXP_BITS) - 1; \
exp -= ONE_EXP(DOUBLE); \
\
/* undefined behavior if truncated value cannot be represented */ \
if (with_sign) { \
if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \
return; \
} else { \
if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */ \
return; \
} \
\
val.high &= (1 << (DOUBLE_FRAC_BITS - 32)) - 1; \
if (exp >= 32) { \
ret.high = 1 << (exp - 32); \
if (exp >= DOUBLE_FRAC_BITS) { \
high_shift = exp - DOUBLE_FRAC_BITS; \
ret.high |= val.high << high_shift; \
ret.high |= val.low >> (32 - high_shift); \
ret.low = val.low << high_shift; \
} else { \
high_shift = DOUBLE_FRAC_BITS - exp; \
ret.high |= val.high >> high_shift; \
ret.low = val.high << (32 - high_shift); \
ret.low |= val.low >> high_shift; \
} \
} else { \
ret.high = 0; \
ret.low = 1 << exp; \
if (exp > DOUBLE_FRAC_BITS - 32) { \
high_shift = exp - (DOUBLE_FRAC_BITS - 32); \
ret.low |= val.high << high_shift; \
ret.low |= val.low >> (32 - high_shift); \
} else \
ret.low |= val.high >> (DOUBLE_FRAC_BITS - 32 - exp); \
} \
\
/* encode negative integer using 2's complement */ \
if (with_sign && sign) { \
ret.low = ~ret.low; \
ret.high = ~ret.high; \
if (ret.low == UINT_MAX) { \
ret.low = 0; \
ret.high++; \
} else \
ret.low++; \
} \
\
_ret_: \
double_unsigned_struct_return(ret); \
}
/* double to unsigned long long conversion */
DEFINE__AEABI_D2XLZ(d2ulz, 0)
/* double to long long conversion */
DEFINE__AEABI_D2XLZ(d2lz, 1)
/* long long to float conversion */
#define DEFINE__AEABI_XL2F(name, with_sign) \
unsigned __aeabi_ ## name(unsigned long long v) \
{ \
int s /* shift */, flb /* first lost bit */, sign = 0; \
unsigned p = 0 /* power */, ret; \
double_unsigned_struct val; \
\
/* fraction in negative float is encoded in 1's complement */ \
if (with_sign && (v & (1ULL << 63))) { \
sign = 1; \
v = ~v + 1; \
} \
val.low = v; \
val.high = v >> 32; \
/* fill fraction bits */ \
for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1); \
if (p) { \
ret = val.high & (p - 1); \
if (s < FLOAT_FRAC_BITS) { \
ret <<= FLOAT_FRAC_BITS - s; \
ret |= val.low >> (32 - (FLOAT_FRAC_BITS - s)); \
flb = (val.low >> (32 - (FLOAT_FRAC_BITS - s - 1))) & 1; \
} else { \
flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1; \
ret >>= s - FLOAT_FRAC_BITS; \
} \
s += 32; \
} else { \
for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1); \
if (p) { \
ret = val.low & (p - 1); \
if (s <= FLOAT_FRAC_BITS) { \
ret <<= FLOAT_FRAC_BITS - s; \
flb = 0; \
} else { \
flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1; \
ret >>= s - FLOAT_FRAC_BITS; \
} \
} else \
return 0; \
} \
if (flb) \
ret++; \
\
/* fill exponent bits */ \
ret |= (s + ONE_EXP(FLOAT)) << FLOAT_FRAC_BITS; \
\
/* fill sign bit */ \
ret |= sign << 31; \
\
return ret; \
}
/* unsigned long long to float conversion */
DEFINE__AEABI_XL2F(ul2f, 0)
/* long long to float conversion */
DEFINE__AEABI_XL2F(l2f, 1)
/* long long to double conversion */
#define __AEABI_XL2D(name, with_sign) \
void __aeabi_ ## name(unsigned long long v) \
{ \
int s /* shift */, high_shift, sign = 0; \
unsigned tmp, p = 0; \
double_unsigned_struct val, ret; \
\
/* fraction in negative float is encoded in 1's complement */ \
if (with_sign && (v & (1ULL << 63))) { \
sign = 1; \
v = ~v + 1; \
} \
val.low = v; \
val.high = v >> 32; \
\
/* fill fraction bits */ \
for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1); \
if (p) { \
tmp = val.high & (p - 1); \
if (s < DOUBLE_FRAC_BITS - 32) { \
high_shift = DOUBLE_FRAC_BITS - 32 - s; \
ret.high = tmp << high_shift; \
ret.high |= val.low >> (32 - high_shift); \
ret.low = val.low << high_shift; \
} else { \
high_shift = s - (DOUBLE_FRAC_BITS - 32); \
ret.high = tmp >> high_shift; \
ret.low = tmp << (32 - high_shift); \
ret.low |= val.low >> high_shift; \
if ((val.low >> (high_shift - 1)) & 1) { \
if (ret.low == UINT_MAX) { \
ret.high++; \
ret.low = 0; \
} else \
ret.low++; \
} \
} \
s += 32; \
} else { \
for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1); \
if (p) { \
tmp = val.low & (p - 1); \
if (s <= DOUBLE_FRAC_BITS - 32) { \
high_shift = DOUBLE_FRAC_BITS - 32 - s; \
ret.high = tmp << high_shift; \
ret.low = 0; \
} else { \
high_shift = s - (DOUBLE_FRAC_BITS - 32); \
ret.high = tmp >> high_shift; \
ret.low = tmp << (32 - high_shift); \
} \
} else { \
ret.high = ret.low = 0; \
goto _ret_; \
} \
} \
\
/* fill exponent bits */ \
ret.high |= (s + ONE_EXP(DOUBLE)) << (DOUBLE_FRAC_BITS - 32); \
\
/* fill sign bit */ \
ret.high |= sign << 31; \
\
_ret_: \
double_unsigned_struct_return(ret); \
}
/* unsigned long long to double conversion */
__AEABI_XL2D(ul2d, 0)
/* long long to double conversion */
__AEABI_XL2D(l2d, 1)
#if 1
/* Long long helper functions */
/* TODO: add error in case of den == 0 (see §4.3.1 and §4.3.2) */
#define define_aeabi_xdivmod_signed_type(basetype, type) \
typedef struct type { \
basetype quot; \
unsigned basetype rem; \
} type
#define define_aeabi_xdivmod_unsigned_type(basetype, type) \
typedef struct type { \
basetype quot; \
basetype rem; \
} type
#define AEABI_UXDIVMOD(name,type, rettype, typemacro) \
static inline rettype aeabi_ ## name (type num, type den) \
{ \
rettype ret; \
type quot = 0; \
\
/* Increase quotient while it is less than numerator */ \
while (num >= den) { \
type q = 1; \
\
/* Find closest power of two */ \
while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \
q <<= 1; \
\
/* Compute difference between current quotient and numerator */ \
num -= q * den; \
quot += q; \
} \
ret.quot = quot; \
ret.rem = num; \
return ret; \
}
#define __AEABI_XDIVMOD(name, type, uiname, rettype, urettype, typemacro) \
void __aeabi_ ## name(type numerator, type denominator) \
{ \
unsigned type num, den; \
urettype uxdiv_ret; \
rettype ret; \
\
if (numerator >= 0) \
num = numerator; \
else \
num = 0 - numerator; \
if (denominator >= 0) \
den = denominator; \
else \
den = 0 - denominator; \
uxdiv_ret = aeabi_ ## uiname(num, den); \
/* signs differ */ \
if ((numerator & typemacro ## _MIN) != (denominator & typemacro ## _MIN)) \
ret.quot = 0 - uxdiv_ret.quot; \
else \
ret.quot = uxdiv_ret.quot; \
if (numerator < 0) \
ret.rem = 0 - uxdiv_ret.rem; \
else \
ret.rem = uxdiv_ret.rem; \
\
rettype ## _return(ret); \
}
define_aeabi_xdivmod_signed_type(long long, lldiv_t);
define_aeabi_xdivmod_unsigned_type(unsigned long long, ulldiv_t);
define_aeabi_xdivmod_signed_type(int, idiv_t);
define_aeabi_xdivmod_unsigned_type(unsigned, uidiv_t);
REGS_RETURN(lldiv_t, lldiv_t)
REGS_RETURN(ulldiv_t, ulldiv_t)
REGS_RETURN(idiv_t, idiv_t)
REGS_RETURN(uidiv_t, uidiv_t)
AEABI_UXDIVMOD(uldivmod, unsigned long long, ulldiv_t, ULLONG)
__AEABI_XDIVMOD(ldivmod, long long, uldivmod, lldiv_t, ulldiv_t, LLONG)
void __aeabi_uldivmod(unsigned long long num, unsigned long long den)
{
ulldiv_t_return(aeabi_uldivmod(num, den));
}
void __aeabi_llsl(double_unsigned_struct val, int shift)
{
double_unsigned_struct ret;
if (shift >= 32) {
val.high = val.low;
val.low = 0;
shift -= 32;
}
if (shift > 0) {
ret.low = val.low << shift;
ret.high = (val.high << shift) | (val.low >> (32 - shift));
double_unsigned_struct_return(ret);
return;
}
double_unsigned_struct_return(val);
}
#define aeabi_lsr(val, shift, fill, type) \
type ## _struct ret; \
\
if (shift >= 32) { \
val.low = val.high; \
val.high = fill; \
shift -= 32; \
} \
if (shift > 0) { \
ret.high = val.high >> shift; \
ret.low = (val.high << (32 - shift)) | (val.low >> shift); \
type ## _struct_return(ret); \
return; \
} \
type ## _struct_return(val);
void __aeabi_llsr(double_unsigned_struct val, int shift)
{
aeabi_lsr(val, shift, 0, double_unsigned);
}
void __aeabi_lasr(unsigned_int_struct val, int shift)
{
aeabi_lsr(val, shift, val.high >> 31, unsigned_int);
}
/* Integer division functions */
#if 0 /* very slow */
AEABI_UXDIVMOD(uidivmod, unsigned, uidiv_t, UINT)
int __aeabi_idiv(int numerator, int denominator)
{
unsigned num, den;
uidiv_t ret;
if (numerator >= 0)
num = numerator;
else
num = 0 - numerator;
if (denominator >= 0)
den = denominator;
else
den = 0 - denominator;
ret = aeabi_uidivmod(num, den);
if ((numerator & INT_MIN) != (denominator & INT_MIN)) /* signs differ */
ret.quot *= -1;
return ret.quot;
}
unsigned __aeabi_uidiv(unsigned num, unsigned den)
{
return aeabi_uidivmod(num, den).quot;
}
__AEABI_XDIVMOD(idivmod, int, uidivmod, idiv_t, uidiv_t, INT)
void __aeabi_uidivmod(unsigned num, unsigned den)
{
uidiv_t_return(aeabi_uidivmod(num, den));
}
#else
# define UIDIVMOD_ASM 1
#endif
/* Some targets do not have all eabi calls (OpenBSD) */
typedef __SIZE_TYPE__ size_t;
extern void *memcpy(void *dest, const void *src, size_t n);
extern void *memmove(void *dest, const void *src, size_t n);
extern void *memset(void *s, int c, size_t n);
void *
__aeabi_memcpy (void *dest, const void *src, size_t n)
{
return memcpy (dest, src, n);
}
void *
__aeabi_memmove (void *dest, const void *src, size_t n)
{
return memmove (dest, src, n);
}
void *
__aeabi_memmove4 (void *dest, const void *src, size_t n)
{
return memmove (dest, src, n);
}
void *
__aeabi_memmove8 (void *dest, const void *src, size_t n)
{
return memmove (dest, src, n);
}
void *
__aeabi_memset (void *s, size_t n, int c)
{
return memset (s, c, n);
}
/* ***************************************************************** */
#if UIDIVMOD_ASM
#include <config.h>
__asm__(
"\n .global __aeabi_idiv, __aeabi_idivmod"
"\n .global __aeabi_uidiv, __aeabi_uidivmod"
#if __ARM_FEATURE_IDIV
"\n__aeabi_idiv:"
"\n__aeabi_idivmod:"
"\n mov r2, r0"
"\n sdiv r0, r0, r1"
"\n mls r1, r1, r0, r2"
"\n bx lr"
"\n__aeabi_uidiv:"
"\n__aeabi_uidivmod:"
"\n mov r2, r0"
"\n udiv r0, r0, r1"
"\n mls r1, r1, r0, r2"
"\n bx lr"
#else
/* Runtime ABI for the ARM Cortex-M0
* idivmod.S: signed 32 bit division (quotient and remainder)
*
* Copyright (c) 2012 Jörg Mische <bobbl@gmx.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*/
"\n__aeabi_idiv:"
"\n__aeabi_idivmod:"
"\n cmp r0, #0"
"\n bge .Lnumerator_pos"
"\n rsb r0, r0, #0" // num = -num
"\n cmp r1, #0"
"\n bge .Lboth_neg"
"\n rsb r1, r1, #0" // den = -den
"\n push {lr}"
"\n bl __aeabi_uidivmod"
"\n rsb r1, r1, #0" // rem = -rem
"\n pop {pc}"
"\n.Lboth_neg:"
"\n push {lr}"
"\n bl __aeabi_uidivmod"
"\n rsb r0, r0, #0" // quot = -quot
"\n rsb r1, r1, #0" // rem = -rem
"\n pop {pc}"
"\n.Ldenom_neg:"
"\n rsb r1, r1, #0" // den = -den
"\n push {lr}"
"\n bl __aeabi_uidivmod"
"\n rsb r0, r0, #0" // quot = -quot
"\n pop {pc}"
"\n.Lnumerator_pos:"
"\n cmp r1, #0"
"\n blt .Ldenom_neg"
// Divide r0 by r1 and return the quotient in r0 and the remainder in r1
"\n__aeabi_uidiv:"
"\n__aeabi_uidivmod:"
// Shift left the denominator until it is greater than the numerator
"\n mov r2, #1" // counter
"\n mov r3, #0" // result
"\n cmp r0, r1"
"\n bls .Lsub_loop"
"\n adds r1, #0" // dont shift if denominator would overflow
"\n bmi .Lsub_loop"
"\n beq .Luidiv0"
"\n.Ldenom_shift_loop:"
"\n lsl r2, #1"
"\n lsls r1, #1"
"\n bmi .Lsub_loop"
"\n cmp r0, r1"
"\n bhi .Ldenom_shift_loop"
"\n.Lsub_loop:"
"\n cmp r0, r1" // if (num >= den)...
"\n subcs r0, r1" // numerator -= denom
"\n orrcs r3, r2" // result(r3) |= bitmask(r2)
"\n lsr r1, #1" // denom(r1) >>= 1
"\n lsrs r2, #1" // bitmask(r2) >>= 1
"\n bne .Lsub_loop"
"\n mov r1, r0" // remainder(r1) = numerator(r0)
"\n mov r0, r3" // quotient(r0) = result(r3)
"\n bx lr"
"\n.Luidiv0:" // XXX: division by zero
"\n mov r0, #0"
"\n bx lr"
#endif
);
#endif /* UIDIVMOD_ASM */
/* ***************************************************************** */
#endif

64
lib/armflush.c Normal file
View File

@ -0,0 +1,64 @@
/* armflush.c - flush the instruction cache
__clear_cache is used in tccrun.c, It is a built-in
intrinsic with gcc. However tcc in order to compile
itself needs this function */
/* ------------------------------------------------------------- */
#if defined __arm__
#ifdef __TINYC__
/* syscall wrapper */
unsigned _tccsyscall(unsigned syscall_nr, ...);
/* arm-tcc supports only fake asm currently */
__asm__(
".global _tccsyscall\n"
"_tccsyscall:\n"
"push {r7, lr}\n\t"
"mov r7, r0\n\t"
"mov r0, r1\n\t"
"mov r1, r2\n\t"
"mov r2, r3\n\t"
"svc #0\n\t"
"pop {r7, pc}"
);
/* from unistd.h: */
#if defined(__thumb__) || defined(__ARM_EABI__)
# define __NR_SYSCALL_BASE 0x0
#else
# define __NR_SYSCALL_BASE 0x900000
#endif
#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000)
#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
#define syscall _tccsyscall
#else
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>
#endif
/* Flushing for tccrun */
void __clear_cache(void *beginning, void *end)
{
/* __ARM_NR_cacheflush is kernel private and should not be used in user space.
* However, there is no ARM asm parser in tcc so we use it for now */
syscall(__ARM_NR_cacheflush, beginning, end, 0);
}
/* ------------------------------------------------------------- */
#elif defined __aarch64__
void __clear_cache(void *beg, void *end)
{
__arm64_clear_cache(beg, end);
}
/* ------------------------------------------------------------- */
#endif

2669
lib/atomic.S Normal file

File diff suppressed because it is too large Load Diff

2261
lib/bcheck.c Normal file

File diff suppressed because it is too large Load Diff

95
lib/bt-dll.c Normal file
View File

@ -0,0 +1,95 @@
/* ------------------------------------------------------------- */
/* stubs for calling bcheck functions from a dll. */
#include <windows.h>
#include <stdio.h>
#define REDIR_ALL \
REDIR(__bt_init) \
REDIR(__bt_exit) \
REDIR(tcc_backtrace) \
\
REDIR(__bound_ptr_add) \
REDIR(__bound_ptr_indir1) \
REDIR(__bound_ptr_indir2) \
REDIR(__bound_ptr_indir4) \
REDIR(__bound_ptr_indir8) \
REDIR(__bound_ptr_indir12) \
REDIR(__bound_ptr_indir16) \
REDIR(__bound_local_new) \
REDIR(__bound_local_delete) \
REDIR(__bound_new_region) \
\
REDIR(__bound_free) \
REDIR(__bound_malloc) \
REDIR(__bound_realloc) \
REDIR(__bound_memcpy) \
REDIR(__bound_memcmp) \
REDIR(__bound_memmove) \
REDIR(__bound_memset) \
REDIR(__bound_strlen) \
REDIR(__bound_strcpy) \
REDIR(__bound_strncpy) \
REDIR(__bound_strcmp) \
REDIR(__bound_strncmp) \
REDIR(__bound_strcat) \
REDIR(__bound_strchr) \
REDIR(__bound_strdup) \
REDIR(__bound_strncat) \
REDIR(__bound_strrchr) \
REDIR(__bound_setjmp) \
REDIR(__bound_longjmp)
#ifdef __leading_underscore
#define _(s) "_"#s
#else
#define _(s) #s
#endif
#define REDIR(s) void *s;
static struct { REDIR_ALL } all_ptrs;
#undef REDIR
#define REDIR(s) #s"\0"
static const char all_names[] = REDIR_ALL;
#undef REDIR
#if __aarch64__
# define REDIR(s) \
__asm__(".global "_(s)";"_(s)":"); \
__asm__(".int 0x58000090"); /* ldr x16, [pc, #16] */ \
__asm__(".int 0xf9400210"); /* ldr x16, [x16] */ \
__asm__(".int 0xd61f0200"); /* br x16 */ \
__asm__(".int 0xd503201f"); /* nop for alignment */ \
__asm__(".quad all_ptrs + (. - all_jmps - 16) / 24 * 8"); \
__asm__(".type "_(s)",function\n.size "_(s)",.-"_(s));
__asm__(".text\n.align 8\nall_jmps:");
REDIR_ALL
#else
# define REDIR(s) \
__asm__(".global "_(s)";"_(s)":"); goto *all_ptrs.s;
static void all_jmps() { REDIR_ALL }
#endif
#undef REDIR
void __bt_init_dll(int bcheck)
{
const char *s = all_names;
void **p = (void**)&all_ptrs;
do {
*p = (void*)GetProcAddress(GetModuleHandle(NULL), (char*)s);
if (NULL == *p) {
char buf[100];
sprintf(buf,
"Error: function '%s()' not found in executable. "
"(Need -bt or -b for linking the exe.)", s);
if (GetStdHandle(STD_ERROR_HANDLE))
fprintf(stderr, "TCC/BCHECK: %s\n", buf), fflush(stderr);
else
MessageBox(NULL, buf, "TCC/BCHECK", MB_ICONERROR);
ExitProcess(1);
}
s = strchr(s,'\0') + 1, ++p;
} while (*s && (bcheck || p < &all_ptrs.__bound_ptr_add));
}

87
lib/bt-exe.c Normal file
View File

@ -0,0 +1,87 @@
/* ------------------------------------------------------------- */
/* for linking rt_printline and the signal/exception handler
from tccrun.c into executables. */
#define CONFIG_TCC_BACKTRACE_ONLY
#define ONE_SOURCE 1
#define pstrcpy tcc_pstrcpy
#include "../tccrun.c"
#ifndef _WIN32
# define __declspec(n)
#endif
#ifdef _WIN64
static void bt_init_pe_prog_base(rt_context *p)
{
MEMORY_BASIC_INFORMATION mbi;
addr_t imagebase;
if (!p->prog_base)
return;
if (!VirtualQuery(p, &mbi, sizeof(mbi)) || !mbi.AllocationBase)
return;
imagebase = (addr_t)mbi.AllocationBase - p->prog_base;
p->prog_base = (addr_t)mbi.AllocationBase - (imagebase & 0xffffffffu);
}
#endif
__declspec(dllexport)
void __bt_init(rt_context *p, int is_exe)
{
__attribute__((weak)) int main();
__attribute__((weak)) void __bound_init(void*, int);
//fprintf(stderr, "__bt_init %d %p %p %p\n", is_exe, p, p->stab_sym, p->bounds_start), fflush(stderr);
/* call __bound_init here due to redirection of sigaction */
/* needed to add global symbols */
if (p->bounds_start)
__bound_init(p->bounds_start, -1);
#ifdef _WIN64
bt_init_pe_prog_base(p);
#endif
/* add to chain */
rt_wait_sem();
p->next = g_rc, g_rc = p;
rt_post_sem();
if (is_exe) {
/* we are the executable (not a dll) */
p->top_func = main;
set_exception_handler();
}
}
__declspec(dllexport)
void __bt_exit(rt_context *p)
{
struct rt_context *rc, **pp;
__attribute__((weak)) void __bound_exit_dll(void*);
//fprintf(stderr, "__bt_exit %d %p\n", !!p->top_func, p);
if (p->bounds_start)
__bound_exit_dll(p->bounds_start);
/* remove from chain */
rt_wait_sem();
for (pp = &g_rc; rc = *pp, rc; pp = &rc->next)
if (rc == p) {
*pp = rc->next;
break;
}
rt_post_sem();
}
/* copy a string and truncate it. */
ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s)
{
int l = strlen(s);
if (l >= buf_size)
l = buf_size - 1;
memcpy(buf, s, l);
buf[l] = 0;
return buf;
}

56
lib/bt-log.c Normal file
View File

@ -0,0 +1,56 @@
/* ------------------------------------------------------------- */
/* function to get a stack backtrace on demand with a message */
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#undef __attribute__
#ifdef _WIN32
# define DLL_EXPORT __declspec(dllexport)
#else
# define DLL_EXPORT
#endif
/* Needed when using ...libtcc1-usegcc=yes in lib/Makefile */
#if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wframe-address"
#endif
typedef struct rt_frame {
void *ip, *fp, *sp;
} rt_frame;
__attribute__((weak))
int _tcc_backtrace(rt_frame *f, const char *fmt, va_list ap);
DLL_EXPORT int tcc_backtrace(const char *fmt, ...)
{
va_list ap;
int ret;
if (_tcc_backtrace) {
rt_frame f;
f.fp = __builtin_frame_address(1);
f.ip = __builtin_return_address(0);
va_start(ap, fmt);
ret = _tcc_backtrace(&f, fmt, ap);
va_end(ap);
} else {
const char *p, *nl = "\n";
if (fmt[0] == '^' && (p = strchr(fmt + 1, fmt[0])))
fmt = p + 1;
if (fmt[0] == '\001')
++fmt, nl = "";
va_start(ap, fmt);
ret = vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "%s", nl), fflush(stderr);
}
return ret;
}
#if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
#pragma GCC diagnostic pop
#endif

164
lib/builtin.c Normal file
View File

@ -0,0 +1,164 @@
/* uses alias to allow building with gcc/clang */
#ifdef __TINYC__
#define BUILTIN(x) __builtin_##x
#define BUILTINN(x) "__builtin_" # x
#else
#define BUILTIN(x) __tcc_builtin_##x
#define BUILTINN(x) "__tcc_builtin_" # x
#endif
/* ---------------------------------------------- */
/* This file implements:
* __builtin_ffs
* __builtin_clz
* __builtin_ctz
* __builtin_clrsb
* __builtin_popcount
* __builtin_parity
* for int, long and long long
*/
static const unsigned char table_1_32[] = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
static const unsigned char table_2_32[32] = {
31, 22, 30, 21, 18, 10, 29, 2, 20, 17, 15, 13, 9, 6, 28, 1,
23, 19, 11, 3, 16, 14, 7, 24, 12, 4, 8, 25, 5, 26, 27, 0
};
static const unsigned char table_1_64[] = {
0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
};
static const unsigned char table_2_64[] = {
63, 16, 62, 7, 15, 36, 61, 3, 6, 14, 22, 26, 35, 47, 60, 2,
9, 5, 28, 11, 13, 21, 42, 19, 25, 31, 34, 40, 46, 52, 59, 1,
17, 8, 37, 4, 23, 27, 48, 10, 29, 12, 43, 20, 32, 41, 53, 18,
38, 24, 49, 30, 44, 33, 54, 39, 50, 45, 55, 51, 56, 57, 58, 0
};
#define FFSI(x) \
return table_1_32[((x & -x) * 0x077cb531u) >> 27] + (x != 0);
#define FFSL(x) \
return table_1_64[((x & -x) * 0x022fdd63cc95386dull) >> 58] + (x != 0);
#define CTZI(x) \
return table_1_32[((x & -x) * 0x077cb531u) >> 27];
#define CTZL(x) \
return table_1_64[((x & -x) * 0x022fdd63cc95386dull) >> 58];
#define CLZI(x) \
x |= x >> 1; \
x |= x >> 2; \
x |= x >> 4; \
x |= x >> 8; \
x |= x >> 16; \
return table_2_32[(x * 0x07c4acddu) >> 27];
#define CLZL(x) \
x |= x >> 1; \
x |= x >> 2; \
x |= x >> 4; \
x |= x >> 8; \
x |= x >> 16; \
x |= x >> 32; \
return table_2_64[x * 0x03f79d71b4cb0a89ull >> 58];
#define POPCOUNTI(x, m) \
x = x - ((x >> 1) & 0x55555555); \
x = (x & 0x33333333) + ((x >> 2) & 0x33333333); \
x = (x + (x >> 4)) & 0xf0f0f0f; \
return ((x * 0x01010101) >> 24) & m;
#define POPCOUNTL(x, m) \
x = x - ((x >> 1) & 0x5555555555555555ull); \
x = (x & 0x3333333333333333ull) + ((x >> 2) & 0x3333333333333333ull); \
x = (x + (x >> 4)) & 0xf0f0f0f0f0f0f0full; \
return ((x * 0x0101010101010101ull) >> 56) & m;
/* Returns one plus the index of the least significant 1-bit of x,
or if x is zero, returns zero. */
int BUILTIN(ffs) (int x) { FFSI(x) }
int BUILTIN(ffsll) (long long x) { FFSL(x) }
#if __SIZEOF_LONG__ == 4
int BUILTIN(ffsl) (long x) __attribute__((alias(BUILTINN(ffs))));
#else
int BUILTIN(ffsl) (long x) __attribute__((alias(BUILTINN(ffsll))));
#endif
/* Returns the number of leading 0-bits in x, starting at the most significant
bit position. If x is 0, the result is undefined. */
int BUILTIN(clz) (unsigned int x) { CLZI(x) }
int BUILTIN(clzll) (unsigned long long x) { CLZL(x) }
#if __SIZEOF_LONG__ == 4
int BUILTIN(clzl) (unsigned long x) __attribute__((alias(BUILTINN(clz))));
#else
int BUILTIN(clzl) (unsigned long x) __attribute__((alias(BUILTINN(clzll))));
#endif
/* Returns the number of trailing 0-bits in x, starting at the least
significant bit position. If x is 0, the result is undefined. */
int BUILTIN(ctz) (unsigned int x) { CTZI(x) }
int BUILTIN(ctzll) (unsigned long long x) { CTZL(x) }
#if __SIZEOF_LONG__ == 4
int BUILTIN(ctzl) (unsigned long x) __attribute__((alias(BUILTINN(ctz))));
#else
int BUILTIN(ctzl) (unsigned long x) __attribute__((alias(BUILTINN(ctzll))));
#endif
/* Returns the number of leading redundant sign bits in x, i.e. the number
of bits following the most significant bit that are identical to it.
There are no special cases for 0 or other values. */
int BUILTIN(clrsb) (int x) { if (x < 0) x = ~x; x <<= 1; CLZI(x) }
int BUILTIN(clrsbll) (long long x) { if (x < 0) x = ~x; x <<= 1; CLZL(x) }
#if __SIZEOF_LONG__ == 4
int BUILTIN(clrsbl) (long x) __attribute__((alias(BUILTINN(clrsb))));
#else
int BUILTIN(clrsbl) (long x) __attribute__((alias(BUILTINN(clrsbll))));
#endif
/* Returns the number of 1-bits in x.*/
int BUILTIN(popcount) (unsigned int x) { POPCOUNTI(x, 0x3f) }
int BUILTIN(popcountll) (unsigned long long x) { POPCOUNTL(x, 0x7f) }
#if __SIZEOF_LONG__ == 4
int BUILTIN(popcountl) (unsigned long x) __attribute__((alias(BUILTINN(popcount))));
#else
int BUILTIN(popcountl ) (unsigned long x) __attribute__((alias(BUILTINN(popcountll))));
#endif
/* Returns the parity of x, i.e. the number of 1-bits in x modulo 2. */
int BUILTIN(parity) (unsigned int x) { POPCOUNTI(x, 0x01) }
int BUILTIN(parityll) (unsigned long long x) { POPCOUNTL(x, 0x01) }
#if __SIZEOF_LONG__ == 4
int BUILTIN(parityl) (unsigned long x) __attribute__((alias(BUILTINN(parity))));
#else
int BUILTIN(parityl) (unsigned long x) __attribute__((alias(BUILTINN(parityll))));
#endif
#ifndef __TINYC__
#if defined(__GNUC__) && (__GNUC__ >= 6)
/* gcc overrides alias from __builtin_ffs... to ffs.. so use assembly code */
__asm__(".globl __builtin_ffs");
__asm__(".set __builtin_ffs,__tcc_builtin_ffs");
__asm__(".globl __builtin_ffsl");
__asm__(".set __builtin_ffsl,__tcc_builtin_ffsl");
__asm__(".globl __builtin_ffsll");
__asm__(".set __builtin_ffsll,__tcc_builtin_ffsll");
#else
int __builtin_ffs(int x) __attribute__((alias("__tcc_builtin_ffs")));
int __builtin_ffsl(long x) __attribute__((alias("__tcc_builtin_ffsl")));
int __builtin_ffsll(long long x) __attribute__((alias("__tcc_builtin_ffsll")));
#endif
int __builtin_clz(unsigned int x) __attribute__((alias("__tcc_builtin_clz")));
int __builtin_clzl(unsigned long x) __attribute__((alias("__tcc_builtin_clzl")));
int __builtin_clzll(unsigned long long x) __attribute__((alias("__tcc_builtin_clzll")));
int __builtin_ctz(unsigned int x) __attribute__((alias("__tcc_builtin_ctz")));
int __builtin_ctzl(unsigned long x) __attribute__((alias("__tcc_builtin_ctzl")));
int __builtin_ctzll(unsigned long long x) __attribute__((alias("__tcc_builtin_ctzll")));
int __builtin_clrsb(int x) __attribute__((alias("__tcc_builtin_clrsb")));
int __builtin_clrsbl(long x) __attribute__((alias("__tcc_builtin_clrsbl")));
int __builtin_clrsbll(long long x) __attribute__((alias("__tcc_builtin_clrsbll")));
int __builtin_popcount(unsigned int x) __attribute__((alias("__tcc_builtin_popcount")));
int __builtin_popcountl(unsigned long x) __attribute__((alias("__tcc_builtin_popcountl")));
int __builtin_popcountll(unsigned long long x) __attribute__((alias("__tcc_builtin_popcountll")));
int __builtin_parity(unsigned int x) __attribute__((alias("__tcc_builtin_parity")));
int __builtin_parityl(unsigned long x) __attribute__((alias("__tcc_builtin_parityl")));
int __builtin_parityll(unsigned long long x) __attribute__((alias("__tcc_builtin_parityll")));
#endif

1
lib/dsohandle.c Normal file
View File

@ -0,0 +1 @@
void * __dso_handle __attribute((visibility("hidden"))) = &__dso_handle;

678
lib/lib-arm64.c Normal file
View File

@ -0,0 +1,678 @@
/*
* TCC runtime library for arm64.
*
* Copyright (c) 2015 Edmund Grimley Evans
*
* Copying and distribution of this file, with or without modification,
* are permitted in any medium without royalty provided the copyright
* notice and this notice are preserved. This file is offered as-is,
* without any warranty.
*/
#ifdef __TINYC__
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
#else
#include <stdint.h>
#include <string.h>
#endif
typedef union {
struct { uint64_t x0, x1; };
long double f;
} u128_t;
typedef union {
uint64_t x;
double f;
} u64_t;
typedef union {
uint32_t x;
float f;
} u32_t;
static long double f3_zero(int sgn)
{
u128_t x = { 0, (uint64_t)sgn << 63 };
return x.f;
}
static long double f3_infinity(int sgn)
{
u128_t x = { 0, (uint64_t)sgn << 63 | 0x7fff000000000000 };
return x.f;
}
static long double f3_NaN(void)
{
#if 0
// ARM's default NaN usually has just the top fraction bit set:
u128_t x = { 0, 0x7fff800000000000 };
#else
// GCC's library sets all fraction bits:
u128_t x = { -1, 0x7fffffffffffffff };
#endif
return x.f;
}
static int fp3_convert_NaN(long double *f, int sgn, u128_t *mnt)
{
u128_t x = { mnt->x0,
mnt->x1 | 0x7fff800000000000 | (uint64_t)sgn << 63 };
*f = x.f;
return 1;
#define fp3_convert_NaN(a,b,c) fp3_convert_NaN(a,b,&c)
}
static int fp3_detect_NaNs(long double *f,
int a_sgn, int a_exp, u128_t *a,
int b_sgn, int b_exp, u128_t *b)
#define a (*a)
#define b (*b)
{
#if 0
// Detect signalling NaNs:
if (a_exp == 32767 && (a.x0 | a.x1 << 16) && !(a.x1 >> 47 & 1))
return fp3_convert_NaN(f, a_sgn, a);
if (b_exp == 32767 && (b.x0 | b.x1 << 16) && !(b.x1 >> 47 & 1))
return fp3_convert_NaN(f, b_sgn, b);
#endif
// Detect quiet NaNs:
if (a_exp == 32767 && (a.x0 | a.x1 << 16))
return fp3_convert_NaN(f, a_sgn, a);
if (b_exp == 32767 && (b.x0 | b.x1 << 16))
return fp3_convert_NaN(f, b_sgn, b);
return 0;
#undef a
#undef b
#define fp3_detect_NaNs(a,b,c,d,e,f,g) fp3_detect_NaNs(a,b,c,&d,e,f,&g)
}
static void f3_unpack(int *sgn, int32_t *exp, u128_t *mnt, long double f)
{
u128_t x;
x.f = f;
*sgn = x.x1 >> 63;
*exp = x.x1 >> 48 & 32767;
x.x1 = x.x1 << 16 >> 16;
if (*exp)
x.x1 |= (uint64_t)1 << 48;
else
*exp = 1;
mnt->f = x.f;
}
static void f3_normalise(int32_t *exp, u128_t *mnt)
{
int sh;
if (!(mnt->x0 | mnt->x1))
return;
if (!mnt->x1) {
mnt->x1 = mnt->x0;
mnt->x0 = 0;
*exp -= 64;
}
for (sh = 32; sh; sh >>= 1) {
if (!(mnt->x1 >> (64 - sh))) {
mnt->x1 = mnt->x1 << sh | mnt->x0 >> (64 - sh);
mnt->x0 = mnt->x0 << sh;
*exp -= sh;
}
}
}
static void f3_sticky_shift(int32_t sh, u128_t *x)
{
if (sh >= 128) {
x->x0 = !!(x->x0 | x->x1);
x->x1 = 0;
return;
}
if (sh >= 64) {
x->x0 = x->x1 | !!x->x0;
x->x1 = 0;
sh -= 64;
}
if (sh > 0) {
x->x0 = x->x0 >> sh | x->x1 << (64 - sh) | !!(x->x0 << (64 - sh));
x->x1 = x->x1 >> sh;
}
}
static long double f3_round(int sgn, int32_t exp, u128_t *x)
{
long double f;
int error;
if (exp > 0) {
f3_sticky_shift(13, x);
}
else {
f3_sticky_shift(14 - exp, x);
exp = 0;
}
error = x->x0 & 3;
x->x0 = x->x0 >> 2 | x->x1 << 62;
x->x1 = x->x1 >> 2;
if (error == 3 || ((error == 2) & (x->x0 & 1))) {
if (!++x->x0) {
++x->x1;
if (x->x1 == (uint64_t)1 << 48)
exp = 1;
else if (x->x1 == (uint64_t)1 << 49) {
++exp;
x->x0 = x->x0 >> 1 | x->x1 << 63;
x->x1 = x->x1 >> 1;
}
}
}
if (exp >= 32767)
return f3_infinity(sgn);
x->x1 = x->x1 << 16 >> 16 | (uint64_t)exp << 48 | (uint64_t)sgn << 63;
return x->f;
}
static long double f3_add(long double fa, long double fb, int neg)
{
u128_t a, b, x;
int32_t a_exp, b_exp, x_exp;
int a_sgn, b_sgn, x_sgn;
long double fx;
f3_unpack(&a_sgn, &a_exp, &a, fa);
f3_unpack(&b_sgn, &b_exp, &b, fb);
if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
return fx;
b_sgn ^= neg;
// Handle infinities and zeroes:
if (a_exp == 32767 && b_exp == 32767 && a_sgn != b_sgn)
return f3_NaN();
if (a_exp == 32767)
return f3_infinity(a_sgn);
if (b_exp == 32767)
return f3_infinity(b_sgn);
if (!(a.x0 | a.x1 | b.x0 | b.x1))
return f3_zero(a_sgn & b_sgn);
a.x1 = a.x1 << 3 | a.x0 >> 61;
a.x0 = a.x0 << 3;
b.x1 = b.x1 << 3 | b.x0 >> 61;
b.x0 = b.x0 << 3;
if (a_exp <= b_exp) {
f3_sticky_shift(b_exp - a_exp, &a);
a_exp = b_exp;
}
else {
f3_sticky_shift(a_exp - b_exp, &b);
b_exp = a_exp;
}
x_sgn = a_sgn;
x_exp = a_exp;
if (a_sgn == b_sgn) {
x.x0 = a.x0 + b.x0;
x.x1 = a.x1 + b.x1 + (x.x0 < a.x0);
}
else {
x.x0 = a.x0 - b.x0;
x.x1 = a.x1 - b.x1 - (x.x0 > a.x0);
if (x.x1 >> 63) {
x_sgn ^= 1;
x.x0 = -x.x0;
x.x1 = -x.x1 - !!x.x0;
}
}
if (!(x.x0 | x.x1))
return f3_zero(0);
f3_normalise(&x_exp, &x);
return f3_round(x_sgn, x_exp + 12, &x);
}
long double __addtf3(long double a, long double b)
{
return f3_add(a, b, 0);
}
long double __subtf3(long double a, long double b)
{
return f3_add(a, b, 1);
}
long double __multf3(long double fa, long double fb)
{
u128_t a, b, x;
int32_t a_exp, b_exp, x_exp;
int a_sgn, b_sgn, x_sgn;
long double fx;
f3_unpack(&a_sgn, &a_exp, &a, fa);
f3_unpack(&b_sgn, &b_exp, &b, fb);
if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
return fx;
// Handle infinities and zeroes:
if ((a_exp == 32767 && !(b.x0 | b.x1)) ||
(b_exp == 32767 && !(a.x0 | a.x1)))
return f3_NaN();
if (a_exp == 32767 || b_exp == 32767)
return f3_infinity(a_sgn ^ b_sgn);
if (!(a.x0 | a.x1) || !(b.x0 | b.x1))
return f3_zero(a_sgn ^ b_sgn);
f3_normalise(&a_exp, &a);
f3_normalise(&b_exp, &b);
x_sgn = a_sgn ^ b_sgn;
x_exp = a_exp + b_exp - 16352;
{
// Convert to base (1 << 30), discarding bottom 6 bits, which are zero,
// so there are (32, 30, 30, 30) bits in (a3, a2, a1, a0):
uint64_t a0 = a.x0 << 28 >> 34;
uint64_t b0 = b.x0 << 28 >> 34;
uint64_t a1 = a.x0 >> 36 | a.x1 << 62 >> 34;
uint64_t b1 = b.x0 >> 36 | b.x1 << 62 >> 34;
uint64_t a2 = a.x1 << 32 >> 34;
uint64_t b2 = b.x1 << 32 >> 34;
uint64_t a3 = a.x1 >> 32;
uint64_t b3 = b.x1 >> 32;
// Use 16 small multiplications and additions that do not overflow:
uint64_t x0 = a0 * b0;
uint64_t x1 = (x0 >> 30) + a0 * b1 + a1 * b0;
uint64_t x2 = (x1 >> 30) + a0 * b2 + a1 * b1 + a2 * b0;
uint64_t x3 = (x2 >> 30) + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
uint64_t x4 = (x3 >> 30) + a1 * b3 + a2 * b2 + a3 * b1;
uint64_t x5 = (x4 >> 30) + a2 * b3 + a3 * b2;
uint64_t x6 = (x5 >> 30) + a3 * b3;
// We now have (64, 30, 30, ...) bits in (x6, x5, x4, ...).
// Take the top 128 bits, setting bottom bit if any lower bits were set:
uint64_t y0 = (x5 << 34 | x4 << 34 >> 30 | x3 << 34 >> 60 |
!!(x3 << 38 | (x2 | x1 | x0) << 34));
uint64_t y1 = x6;
// Top bit may be zero. Renormalise:
if (!(y1 >> 63)) {
y1 = y1 << 1 | y0 >> 63;
y0 = y0 << 1;
--x_exp;
}
x.x0 = y0;
x.x1 = y1;
}
return f3_round(x_sgn, x_exp, &x);
}
long double __divtf3(long double fa, long double fb)
{
u128_t a, b, x;
int32_t a_exp, b_exp, x_exp;
int a_sgn, b_sgn, x_sgn, i;
long double fx;
f3_unpack(&a_sgn, &a_exp, &a, fa);
f3_unpack(&b_sgn, &b_exp, &b, fb);
if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
return fx;
// Handle infinities and zeroes:
if ((a_exp == 32767 && b_exp == 32767) ||
(!(a.x0 | a.x1) && !(b.x0 | b.x1)))
return f3_NaN();
if (a_exp == 32767 || !(b.x0 | b.x1))
return f3_infinity(a_sgn ^ b_sgn);
if (!(a.x0 | a.x1) || b_exp == 32767)
return f3_zero(a_sgn ^ b_sgn);
f3_normalise(&a_exp, &a);
f3_normalise(&b_exp, &b);
x_sgn = a_sgn ^ b_sgn;
x_exp = a_exp - b_exp + 16395;
a.x0 = a.x0 >> 1 | a.x1 << 63;
a.x1 = a.x1 >> 1;
b.x0 = b.x0 >> 1 | b.x1 << 63;
b.x1 = b.x1 >> 1;
x.x0 = 0;
x.x1 = 0;
for (i = 0; i < 116; i++) {
x.x1 = x.x1 << 1 | x.x0 >> 63;
x.x0 = x.x0 << 1;
if (a.x1 > b.x1 || (a.x1 == b.x1 && a.x0 >= b.x0)) {
a.x1 = a.x1 - b.x1 - (a.x0 < b.x0);
a.x0 = a.x0 - b.x0;
x.x0 |= 1;
}
a.x1 = a.x1 << 1 | a.x0 >> 63;
a.x0 = a.x0 << 1;
}
x.x0 |= !!(a.x0 | a.x1);
f3_normalise(&x_exp, &x);
return f3_round(x_sgn, x_exp, &x);
}
long double __negtf2(long double f)
{
((u128_t*)&f)->x1 ^= 1UL << 63;
return f;
}
long double __extendsftf2(float f)
{
u128_t x;
u32_t u;
uint32_t a;
uint64_t aa;
u.f = f, a = u.x;
aa = a;
x.x0 = 0;
if (!(a << 1))
x.x1 = aa << 32;
else if (a << 1 >> 24 == 255)
x.x1 = (0x7fff000000000000 | aa >> 31 << 63 | aa << 41 >> 16 |
(uint64_t)!!(a << 9) << 47);
else if (a << 1 >> 24 == 0) {
uint64_t adj = 0;
while (!(a << 1 >> 1 >> (23 - adj)))
adj++;
x.x1 = aa >> 31 << 63 | (16256 - adj + 1) << 48 | aa << adj << 41 >> 16;
} else
x.x1 = (aa >> 31 << 63 | ((aa >> 23 & 255) + 16256) << 48 |
aa << 41 >> 16);
return x.f;
}
long double __extenddftf2(double f)
{
u128_t x;
u64_t u;
uint64_t a;
u.f = f, a = u.x;
x.x0 = a << 60;
if (!(a << 1))
x.x1 = a;
else if (a << 1 >> 53 == 2047)
x.x1 = (0x7fff000000000000 | a >> 63 << 63 | a << 12 >> 16 |
(uint64_t)!!(a << 12) << 47);
else if (a << 1 >> 53 == 0) {
uint64_t adj = 0;
while (!(a << 1 >> 1 >> (52 - adj)))
adj++;
x.x0 <<= adj;
x.x1 = a >> 63 << 63 | (15360 - adj + 1) << 48 | a << adj << 12 >> 16;
} else
x.x1 = a >> 63 << 63 | ((a >> 52 & 2047) + 15360) << 48 | a << 12 >> 16;
return x.f;
}
float __trunctfsf2(long double f)
{
u128_t mnt;
int32_t exp;
int sgn;
u32_t x;
#define x x.x
f3_unpack(&sgn, &exp, &mnt, f);
if (exp == 32767 && (mnt.x0 | mnt.x1 << 16))
x = 0x7fc00000 | (uint32_t)sgn << 31 | (mnt.x1 >> 25 & 0x007fffff);
else if (exp > 16510)
x = 0x7f800000 | (uint32_t)sgn << 31;
else if (exp < 16233)
x = (uint32_t)sgn << 31;
else {
exp -= 16257;
x = mnt.x1 >> 23 | !!(mnt.x0 | mnt.x1 << 41);
if (exp < 0) {
x = x >> -exp | !!(x << (32 + exp));
exp = 0;
}
if ((x & 3) == 3 || (x & 7) == 6)
x += 4;
x = ((x >> 2) + (exp << 23)) | (uint32_t)sgn << 31;
}
#undef x
return x.f;
}
double __trunctfdf2(long double f)
{
u128_t mnt;
int32_t exp;
int sgn;
u64_t x;
#define x x.x
f3_unpack(&sgn, &exp, &mnt, f);
if (exp == 32767 && (mnt.x0 | mnt.x1 << 16))
x = (0x7ff8000000000000 | (uint64_t)sgn << 63 |
mnt.x1 << 16 >> 12 | mnt.x0 >> 60);
else if (exp > 17406)
x = 0x7ff0000000000000 | (uint64_t)sgn << 63;
else if (exp < 15308)
x = (uint64_t)sgn << 63;
else {
exp -= 15361;
x = mnt.x1 << 6 | mnt.x0 >> 58 | !!(mnt.x0 << 6);
if (exp < 0) {
x = x >> -exp | !!(x << (64 + exp));
exp = 0;
}
if ((x & 3) == 3 || (x & 7) == 6)
x += 4;
x = ((x >> 2) + ((uint64_t)exp << 52)) | (uint64_t)sgn << 63;
}
#undef x
return x.f;
}
int32_t __fixtfsi(long double fa)
{
u128_t a;
int32_t a_exp;
int a_sgn;
int32_t x;
f3_unpack(&a_sgn, &a_exp, &a, fa);
if (a_exp < 16369)
return 0;
if (a_exp > 16413)
return a_sgn ? -0x80000000 : 0x7fffffff;
x = a.x1 >> (16431 - a_exp);
return a_sgn ? -x : x;
}
int64_t __fixtfdi(long double fa)
{
u128_t a;
int32_t a_exp;
int a_sgn;
int64_t x;
f3_unpack(&a_sgn, &a_exp, &a, fa);
if (a_exp < 16383)
return 0;
if (a_exp > 16445)
return a_sgn ? -0x8000000000000000 : 0x7fffffffffffffff;
x = (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp);
return a_sgn ? -x : x;
}
uint32_t __fixunstfsi(long double fa)
{
u128_t a;
int32_t a_exp;
int a_sgn;
f3_unpack(&a_sgn, &a_exp, &a, fa);
if (a_sgn || a_exp < 16369)
return 0;
if (a_exp > 16414)
return -1;
return a.x1 >> (16431 - a_exp);
}
uint64_t __fixunstfdi(long double fa)
{
u128_t a;
int32_t a_exp;
int a_sgn;
f3_unpack(&a_sgn, &a_exp, &a, fa);
if (a_sgn || a_exp < 16383)
return 0;
if (a_exp > 16446)
return -1;
return (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp);
}
long double __floatsitf(int32_t a)
{
int sgn = 0;
int exp = 16414;
uint32_t mnt = a;
u128_t x = { 0, 0 };
int i;
if (a) {
if (a < 0) {
sgn = 1;
mnt = -mnt;
}
for (i = 16; i; i >>= 1)
if (!(mnt >> (32 - i))) {
mnt <<= i;
exp -= i;
}
x.x1 = ((uint64_t)sgn << 63 | (uint64_t)exp << 48 |
(uint64_t)(mnt << 1) << 16);
}
return x.f;
}
long double __floatditf(int64_t a)
{
int sgn = 0;
int exp = 16446;
uint64_t mnt = a;
u128_t x = { 0, 0 };
int i;
if (a) {
if (a < 0) {
sgn = 1;
mnt = -mnt;
}
for (i = 32; i; i >>= 1)
if (!(mnt >> (64 - i))) {
mnt <<= i;
exp -= i;
}
x.x0 = mnt << 49;
x.x1 = (uint64_t)sgn << 63 | (uint64_t)exp << 48 | mnt << 1 >> 16;
}
return x.f;
}
long double __floatunsitf(uint32_t a)
{
int exp = 16414;
uint32_t mnt = a;
u128_t x = { 0, 0 };
int i;
if (a) {
for (i = 16; i; i >>= 1)
if (!(mnt >> (32 - i))) {
mnt <<= i;
exp -= i;
}
x.x1 = (uint64_t)exp << 48 | (uint64_t)(mnt << 1) << 16;
}
return x.f;
}
long double __floatunditf(uint64_t a)
{
int exp = 16446;
uint64_t mnt = a;
u128_t x = { 0, 0 };
long double f;
int i;
if (a) {
for (i = 32; i; i >>= 1)
if (!(mnt >> (64 - i))) {
mnt <<= i;
exp -= i;
}
x.x0 = mnt << 49;
x.x1 = (uint64_t)exp << 48 | mnt << 1 >> 16;
}
return x.f;
}
static int f3_cmp(long double fa, long double fb)
{
u128_t a, b;
a.f = fa;
b.f = fb;
return (!(a.x0 | a.x1 << 1 | b.x0 | b.x1 << 1) ? 0 :
((a.x1 << 1 >> 49 == 0x7fff && (a.x0 | a.x1 << 16)) ||
(b.x1 << 1 >> 49 == 0x7fff && (b.x0 | b.x1 << 16))) ? 2 :
a.x1 >> 63 != b.x1 >> 63 ? (int)(b.x1 >> 63) - (int)(a.x1 >> 63) :
a.x1 < b.x1 ? (int)(a.x1 >> 63 << 1) - 1 :
a.x1 > b.x1 ? 1 - (int)(a.x1 >> 63 << 1) :
a.x0 < b.x0 ? (int)(a.x1 >> 63 << 1) - 1 :
b.x0 < a.x0 ? 1 - (int)(a.x1 >> 63 << 1) : 0);
}
int __eqtf2(long double a, long double b)
{
return !!f3_cmp(a, b);
}
int __netf2(long double a, long double b)
{
return !!f3_cmp(a, b);
}
int __lttf2(long double a, long double b)
{
return f3_cmp(a, b);
}
int __letf2(long double a, long double b)
{
return f3_cmp(a, b);
}
int __gttf2(long double a, long double b)
{
return -f3_cmp(b, a);
}
int __getf2(long double a, long double b)
{
return -f3_cmp(b, a);
}

20
lib/lib-riscv.c Normal file
View File

@ -0,0 +1,20 @@
/*
* TCC runtime library for riscv64.
*
* Copyright (c) 2026
*
* Copying and distribution of this file, with or without modification,
* are permitted in any medium without royalty provided the copyright
* notice and this notice are preserved. This file is offered as-is,
* without any warranty.
*/
/* ------------------------------------------------------------- */
/* __clear_cache is used in tccrun.c. It is a built-in
intrinsic with gcc. However tcc in order to compile
itself needs this function */
void __clear_cache(void *beg, void *end)
{
__riscv64_clear_cache(beg, end);
}

View File

@ -89,13 +89,13 @@ union double_long {
double d;
#if 1
struct {
unsigned long lower;
long upper;
unsigned int lower;
int upper;
} l;
#else
struct {
long upper;
unsigned long lower;
int upper;
unsigned int lower;
} l;
#endif
long long ll;
@ -103,11 +103,13 @@ union double_long {
union float_long {
float f;
long l;
unsigned int l;
};
/* XXX: we don't support several builtin supports for now */
#if defined __i386__
/* XXX: use gcc/tcc intrinsic ? */
#if defined(__i386__)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("subl %5,%1\n\tsbbl %3,%0" \
: "=r" ((USItype) (sh)), \
@ -136,9 +138,6 @@ union float_long {
: "=r" (__cbtmp) : "rm" ((USItype) (x))); \
(count) = __cbtmp ^ 31; \
} while (0)
#else
#error unsupported CPU type
#endif
/* most of this code is taken from libgcc2.c from gcc */
@ -159,7 +158,7 @@ static UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
n0 = nn.s.low;
n1 = nn.s.high;
#if !UDIV_NEEDS_NORMALIZATION
#if !defined(UDIV_NEEDS_NORMALIZATION)
if (d1 == 0)
{
if (d0 > n1)
@ -419,7 +418,7 @@ unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
}
/* XXX: fix tcc's code generator to do this instead */
long long __sardi3(long long a, int b)
long long __ashrdi3(long long a, int b)
{
#ifdef __TINYC__
DWunion u;
@ -438,7 +437,7 @@ long long __sardi3(long long a, int b)
}
/* XXX: fix tcc's code generator to do this instead */
unsigned long long __shrdi3(unsigned long long a, int b)
unsigned long long __lshrdi3(unsigned long long a, int b)
{
#ifdef __TINYC__
DWunion u;
@ -457,7 +456,7 @@ unsigned long long __shrdi3(unsigned long long a, int b)
}
/* XXX: fix tcc's code generator to do this instead */
long long __shldi3(long long a, int b)
long long __ashldi3(long long a, int b)
{
#ifdef __TINYC__
DWunion u;
@ -475,15 +474,10 @@ long long __shldi3(long long a, int b)
#endif
}
#if defined(__i386__)
/* FPU control word for rounding to nearest mode */
unsigned short __tcc_fpu_control = 0x137f;
/* FPU control word for round to zero mode for int conversion */
unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00;
#endif
#endif /* __i386__ */
/* XXX: fix tcc's code generator to do this instead */
float __ulltof(unsigned long long a)
float __floatundisf(unsigned long long a)
{
DWunion uu;
XFtype r;
@ -498,7 +492,7 @@ float __ulltof(unsigned long long a)
}
}
double __ulltod(unsigned long long a)
double __floatundidf(unsigned long long a)
{
DWunion uu;
XFtype r;
@ -513,7 +507,7 @@ double __ulltod(unsigned long long a)
}
}
long double __ulltold(unsigned long long a)
long double __floatundixf(unsigned long long a)
{
DWunion uu;
XFtype r;
@ -532,7 +526,7 @@ unsigned long long __fixunssfdi (float a1)
{
register union float_long fl1;
register int exp;
register unsigned long l;
register unsigned long long l;
fl1.f = a1;
@ -540,16 +534,26 @@ unsigned long long __fixunssfdi (float a1)
return (0);
exp = EXP (fl1.l) - EXCESS - 24;
l = MANT(fl1.l);
if (exp >= 41)
return (unsigned long long)-1;
return 1ULL << 63;
else if (exp >= 0)
return (unsigned long long)l << exp;
l <<= exp;
else if (exp >= -23)
return l >> -exp;
l >>= -exp;
else
return 0;
return 0;
if (SIGN(fl1.l))
l = (unsigned long long)-l;
return l;
}
long long __fixsfdi (float a1)
{
long long ret; int s;
ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1);
return s ? ret : -ret;
}
unsigned long long __fixunsdfdi (double a1)
@ -564,19 +568,29 @@ unsigned long long __fixunsdfdi (double a1)
return (0);
exp = EXPD (dl1) - EXCESSD - 53;
l = MANTD_LL(dl1);
if (exp >= 12)
return (unsigned long long)-1;
return 1ULL << 63; /* overflow result (like gcc, somewhat) */
else if (exp >= 0)
return l << exp;
l <<= exp;
else if (exp >= -52)
return l >> -exp;
l >>= -exp;
else
return 0;
if (SIGND(dl1))
l = (unsigned long long)-l;
return l;
}
long long __fixdfdi (double a1)
{
long long ret; int s;
ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1);
return s ? ret : -ret;
}
#ifndef __arm__
unsigned long long __fixunsxfdi (long double a1)
{
register union ldouble_long dl1;
@ -589,14 +603,21 @@ unsigned long long __fixunsxfdi (long double a1)
return (0);
exp = EXPLD (dl1) - EXCESSLD - 64;
l = dl1.l.lower;
if (exp > 0)
return (unsigned long long)-1;
else if (exp >= -63)
return l >> -exp;
else
return 1ULL << 63;
if (exp < -63)
return 0;
l >>= -exp;
if (SIGNLD(dl1))
l = (unsigned long long)-l;
return l;
}
long long __fixxfdi (long double a1)
{
long long ret; int s;
ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1);
return s ? ret : -ret;
}
#endif /* !ARM */

39
lib/pic86.S Normal file
View File

@ -0,0 +1,39 @@
/* ---------------------------------------------- */
/* get_pc_thunk.S */
#ifdef __leading_underscore
# define _(s) _##s
#else
# define _(s) s
#endif
/* ---------------------------------------------- */
.text
.globl _(__x86.get_pc_thunk.ax)
.hidden _(__x86.get_pc_thunk.ax)
_(__x86.get_pc_thunk.ax):
mov (%esp),%eax
ret
.size _(__x86.get_pc_thunk.ax), .-_(__x86.get_pc_thunk.ax)
.globl _(__x86.get_pc_thunk.bx)
.hidden _(__x86.get_pc_thunk.bx)
_(__x86.get_pc_thunk.bx):
mov (%esp),%ebx
ret
.size _(__x86.get_pc_thunk.bx), .-_(__x86.get_pc_thunk.bx)
.globl _(__x86.get_pc_thunk.cx)
.hidden _(__x86.get_pc_thunk.cx)
_(__x86.get_pc_thunk.cx):
mov (%esp),%ecx
ret
.size _(__x86.get_pc_thunk.cx), .-_(__x86.get_pc_thunk.cx)
.globl _(__x86.get_pc_thunk.dx)
.hidden _(__x86.get_pc_thunk.dx)
_(__x86.get_pc_thunk.dx):
mov (%esp),%edx
ret
.size _(__x86.get_pc_thunk.dx), .-_(__x86.get_pc_thunk.dx)

86
lib/runmain.c Normal file
View File

@ -0,0 +1,86 @@
/* ------------------------------------------------------------- */
/* support for tcc_run() */
#ifdef __leading_underscore
# define _(s) s
#else
# define _(s) _##s
#endif
#ifndef _WIN32
extern void (*_(_init_array_start)[]) (int argc, char **argv, char **envp);
extern void (*_(_init_array_end)[]) (int argc, char **argv, char **envp);
static void run_ctors(int argc, char **argv, char **env)
{
int i = 0;
while (&_(_init_array_start)[i] != _(_init_array_end))
(*_(_init_array_start)[i++])(argc, argv, env);
}
#endif
extern void (*_(_fini_array_start)[]) (void);
extern void (*_(_fini_array_end)[]) (void);
static void run_dtors(void)
{
int i = 0;
while (&_(_fini_array_end)[i] != _(_fini_array_start))
(*_(_fini_array_end)[--i])();
}
static void *rt_exitfunc[32];
static void *rt_exitarg[32];
static int __rt_nr_exit;
void __run_on_exit(int ret)
{
int n = __rt_nr_exit;
while (n)
--n, ((void(*)(int,void*))rt_exitfunc[n])(ret, rt_exitarg[n]);
}
int on_exit(void *function, void *arg)
{
int n = __rt_nr_exit;
if (n < 32) {
rt_exitfunc[n] = function;
rt_exitarg[n] = arg;
__rt_nr_exit = n + 1;
return 0;
}
return 1;
}
int atexit(void (*function)(void))
{
return on_exit(function, 0);
}
typedef struct rt_frame {
void *ip, *fp, *sp;
} rt_frame;
__attribute__((noreturn)) void __rt_exit(rt_frame *, int);
void exit(int code)
{
rt_frame f;
run_dtors();
__run_on_exit(code);
f.fp = 0;
f.ip = exit;
__rt_exit(&f, code);
}
#ifndef _WIN32
int main(int, char**, char**);
int _runmain(int argc, char **argv, char **envp)
{
int ret;
run_ctors(argc, argv, envp);
ret = main(argc, argv, envp);
run_dtors();
__run_on_exit(ret);
return ret;
}
#endif

104
lib/stdatomic.c Normal file
View File

@ -0,0 +1,104 @@
// for libtcc1, avoid including files that are not part of tcc
// #include <stdint.h>
#define uint8_t unsigned char
#define uint16_t unsigned short
#define uint32_t unsigned int
#define uint64_t unsigned long long
#define bool _Bool
#define false 0
#define true 1
#define __ATOMIC_RELAXED 0
#define __ATOMIC_CONSUME 1
#define __ATOMIC_ACQUIRE 2
#define __ATOMIC_RELEASE 3
#define __ATOMIC_ACQ_REL 4
#define __ATOMIC_SEQ_CST 5
typedef __SIZE_TYPE__ size_t;
#define ATOMIC_GEN_OP(TYPE, MODE, NAME, OP, RET) \
TYPE __atomic_##NAME##_##MODE(volatile void *atom, TYPE value, int memorder) \
{ \
TYPE xchg, cmp; \
__atomic_load((TYPE *)atom, (TYPE *)&cmp, __ATOMIC_RELAXED); \
do { \
xchg = (OP); \
} while (!__atomic_compare_exchange((TYPE *)atom, &cmp, &xchg, true, \
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)); \
return RET; \
}
#define ATOMIC_EXCHANGE(TYPE, MODE) \
ATOMIC_GEN_OP(TYPE, MODE, exchange, value, cmp)
#define ATOMIC_ADD_FETCH(TYPE, MODE) \
ATOMIC_GEN_OP(TYPE, MODE, add_fetch, (cmp + value), xchg)
#define ATOMIC_SUB_FETCH(TYPE, MODE) \
ATOMIC_GEN_OP(TYPE, MODE, sub_fetch, (cmp - value), xchg)
#define ATOMIC_AND_FETCH(TYPE, MODE) \
ATOMIC_GEN_OP(TYPE, MODE, and_fetch, (cmp & value), xchg)
#define ATOMIC_OR_FETCH(TYPE, MODE) \
ATOMIC_GEN_OP(TYPE, MODE, or_fetch, (cmp | value), xchg)
#define ATOMIC_XOR_FETCH(TYPE, MODE) \
ATOMIC_GEN_OP(TYPE, MODE, xor_fetch, (cmp ^ value), xchg)
#define ATOMIC_NAND_FETCH(TYPE, MODE) \
ATOMIC_GEN_OP(TYPE, MODE, nand_fetch, ~(cmp & value), xchg)
#define ATOMIC_FETCH_ADD(TYPE, MODE) \
ATOMIC_GEN_OP(TYPE, MODE, fetch_add, (cmp + value), cmp)
#define ATOMIC_FETCH_SUB(TYPE, MODE) \
ATOMIC_GEN_OP(TYPE, MODE, fetch_sub, (cmp - value), cmp)
#define ATOMIC_FETCH_AND(TYPE, MODE) \
ATOMIC_GEN_OP(TYPE, MODE, fetch_and, (cmp & value), cmp)
#define ATOMIC_FETCH_OR(TYPE, MODE) \
ATOMIC_GEN_OP(TYPE, MODE, fetch_or, (cmp | value), cmp)
#define ATOMIC_FETCH_XOR(TYPE, MODE) \
ATOMIC_GEN_OP(TYPE, MODE, fetch_xor, (cmp ^ value), cmp)
#define ATOMIC_FETCH_NAND(TYPE, MODE) \
ATOMIC_GEN_OP(TYPE, MODE, fetch_nand, ~(cmp & value), cmp)
#define ATOMIC_GEN(TYPE, SIZE) \
ATOMIC_EXCHANGE(TYPE, SIZE) \
ATOMIC_ADD_FETCH(TYPE, SIZE) \
ATOMIC_SUB_FETCH(TYPE, SIZE) \
ATOMIC_AND_FETCH(TYPE, SIZE) \
ATOMIC_OR_FETCH(TYPE, SIZE) \
ATOMIC_XOR_FETCH(TYPE, SIZE) \
ATOMIC_NAND_FETCH(TYPE, SIZE) \
ATOMIC_FETCH_ADD(TYPE, SIZE) \
ATOMIC_FETCH_SUB(TYPE, SIZE) \
ATOMIC_FETCH_AND(TYPE, SIZE) \
ATOMIC_FETCH_OR(TYPE, SIZE) \
ATOMIC_FETCH_XOR(TYPE, SIZE) \
ATOMIC_FETCH_NAND(TYPE, SIZE)
ATOMIC_GEN(uint8_t, 1)
ATOMIC_GEN(uint16_t, 2)
ATOMIC_GEN(uint32_t, 4)
ATOMIC_GEN(uint64_t, 8)
/* uses alias to allow building with gcc/clang */
#ifdef __TINYC__
#define ATOMIC(x) __atomic_##x
#else
#define ATOMIC(x) __tcc_atomic_##x
#endif
bool ATOMIC(is_lock_free) (unsigned long size, const volatile void *ptr)
{
bool ret;
switch (size) {
case 1: ret = true; break;
case 2: ret = true; break;
case 4: ret = true; break;
#if defined __x86_64__ || defined __aarch64__ || defined __riscv
case 8: ret = true; break;
#else
case 8: ret = false; break;
#endif
default: ret = false; break;
}
return ret;
}
#ifndef __TINYC__
bool __atomic_is_lock_free(unsigned long size, const volatile void *ptr) __attribute__((alias("__tcc_atomic_is_lock_free")));
#endif

428
lib/tcov.c Normal file
View File

@ -0,0 +1,428 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#ifndef _WIN32
#include <unistd.h>
#include <errno.h>
#else
#include <windows.h>
#include <io.h>
#endif
/* section layout (all little endian):
32bit offset to executable/so file name
filename \0
function name \0
align to 64 bits
64bit function start line
64bits end_line(28bits) / start_line(28bits) / flag=0xff(8bits)
64bits counter
\0
\0
\0
executable/so file name \0
*/
typedef struct tcov_line {
unsigned int fline;
unsigned int lline;
unsigned long long count;
} tcov_line;
typedef struct tcov_function {
char *function;
unsigned int first_line;
unsigned int n_line;
unsigned int m_line;
tcov_line *line;
} tcov_function;
typedef struct tcov_file {
char *filename;
unsigned int n_func;
unsigned int m_func;
tcov_function *func;
struct tcov_file *next;
} tcov_file;
static FILE *open_tcov_file (char *cov_filename)
{
int fd;
#ifndef _WIN32
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0; /* Until EOF. */
lock.l_pid = getpid ();
#endif
fd = open (cov_filename, O_RDWR | O_CREAT, 0666);
if (fd < 0)
return NULL;
#ifndef _WIN32
while (fcntl (fd, F_SETLKW, &lock) && errno == EINTR)
continue;
#else
{
OVERLAPPED overlapped = { 0 };
LockFileEx((HANDLE)_get_osfhandle(fd), LOCKFILE_EXCLUSIVE_LOCK,
0, 1, 0, &overlapped);
}
#endif
return fdopen (fd, "r+");
}
static unsigned long long get_value(unsigned char *p, int size)
{
unsigned long long value = 0;
p += size;
while (size--)
value = (value << 8) | *--p;
return value;
}
static int sort_func (const void *p, const void *q)
{
const tcov_function *pp = (const tcov_function *) p;
const tcov_function *pq = (const tcov_function *) q;
return pp->first_line > pq->first_line ? 1 :
pp->first_line < pq->first_line ? -1 : 0;
}
static int sort_line (const void *p, const void *q)
{
const tcov_line *pp = (const tcov_line *) p;
const tcov_line *pq = (const tcov_line *) q;
return pp->fline > pq->fline ? 1 :
pp->fline < pq->fline ? -1 :
pp->count < pq->count ? 1 :
pp->count > pq->count ? -1 : 0;
}
/* sort to let inline functions work */
static tcov_file *sort_test_coverage (unsigned char *p)
{
int i, j, k;
unsigned char *start = p;
tcov_file *file = NULL;
tcov_file *nfile;
p += 4;
while (*p) {
char *filename = (char *)p;
size_t len = strlen (filename);
nfile = file;
while (nfile) {
if (strcmp (nfile->filename, filename) == 0)
break;
nfile = nfile->next;
}
if (nfile == NULL) {
nfile = malloc (sizeof(tcov_file));
if (nfile == NULL) {
fprintf (stderr, "Malloc error test_coverage\n");
return file;
}
nfile->filename = filename;
nfile->n_func = 0;
nfile->m_func = 0;
nfile->func = NULL;
nfile->next = NULL;
if (file == NULL)
file = nfile;
else {
tcov_file *lfile = file;
while (lfile->next)
lfile = lfile->next;
lfile->next = nfile;
}
}
p += len + 1;
while (*p) {
int i;
char *function = (char *)p;
tcov_function *func;
p += strlen (function) + 1;
p += -(p - start) & 7;
for (i = 0; i < nfile->n_func; i++) {
func = &nfile->func[i];
if (strcmp (func->function, function) == 0)
break;
}
if (i == nfile->n_func) {
if (nfile->n_func >= nfile->m_func) {
nfile->m_func = nfile->m_func == 0 ? 4 : nfile->m_func * 2;
nfile->func = realloc (nfile->func,
nfile->m_func *
sizeof (tcov_function));
if (nfile->func == NULL) {
fprintf (stderr, "Realloc error test_coverage\n");
return file;
}
}
func = &nfile->func[nfile->n_func++];
func->function = function;
func->first_line = get_value (p, 8);
func->n_line = 0;
func->m_line = 0;
func->line = NULL;
}
p += 8;
while (*p) {
tcov_line *line;
unsigned long long val;
if (func->n_line >= func->m_line) {
func->m_line = func->m_line == 0 ? 4 : func->m_line * 2;
func->line = realloc (func->line,
func->m_line * sizeof (tcov_line));
if (func->line == NULL) {
fprintf (stderr, "Realloc error test_coverage\n");
return file;
}
}
line = &func->line[func->n_line++];
val = get_value (p, 8);
line->fline = (val >> 8) & 0xfffffffULL;
line->lline = val >> 36;
line->count = get_value (p + 8, 8);
p += 16;
}
p++;
}
p++;
}
nfile = file;
while (nfile) {
qsort (nfile->func, nfile->n_func, sizeof (tcov_function), sort_func);
for (i = 0; i < nfile->n_func; i++) {
tcov_function *func = &nfile->func[i];
qsort (func->line, func->n_line, sizeof (tcov_line), sort_line);
}
nfile = nfile->next;
}
return file;
}
/* merge with previous tcov file */
static void merge_test_coverage (tcov_file *file, FILE *fp,
unsigned int *pruns)
{
unsigned int runs;
char *p;
char str[10000];
*pruns = 1;
if (fp == NULL)
return;
if (fgets(str, sizeof(str), fp) &&
(p = strrchr (str, ':')) &&
(sscanf (p + 1, "%u", &runs) == 1))
*pruns = runs + 1;
while (file) {
int i;
size_t len = strlen (file->filename);
while (fgets(str, sizeof(str), fp) &&
(p = strstr(str, "0:File:")) == NULL) {}
if ((p = strstr(str, "0:File:")) == NULL ||
strncmp (p + strlen("0:File:"), file->filename, len) != 0 ||
p[strlen("0:File:") + len] != ' ')
break;
for (i = 0; i < file->n_func; i++) {
int j;
tcov_function *func = &file->func[i];
unsigned int next_zero = 0;
unsigned int curline = 0;
for (j = 0; j < func->n_line; j++) {
tcov_line *line = &func->line[j];
unsigned int fline = line->fline;
unsigned long long count;
unsigned int tmp;
char c;
while (curline < fline &&
fgets(str, sizeof(str), fp))
if ((p = strchr(str, ':')) &&
sscanf (p + 1, "%u", &tmp) == 1)
curline = tmp;
if (sscanf (str, "%llu%c\n", &count, &c) == 2) {
if (next_zero == 0)
line->count += count;
next_zero = c == '*';
}
}
}
file = file->next;
}
}
/* store tcov data in file */
void __store_test_coverage (unsigned char * p)
{
int i, j;
unsigned int files;
unsigned int funcs;
unsigned int blocks;
unsigned int blocks_run;
unsigned int runs;
char *cov_filename = (char *)p + get_value (p, 4);
FILE *fp;
char *q;
tcov_file *file;
tcov_file *nfile;
tcov_function *func;
fp = open_tcov_file (cov_filename);
if (fp == NULL) {
fprintf (stderr, "Cannot create coverage file: %s\n", cov_filename);
return;
}
file = sort_test_coverage (p);
merge_test_coverage (file, fp, &runs);
fseek (fp, 0, SEEK_SET);
fprintf (fp, " -: 0:Runs:%u\n", runs);
files = 0;
funcs = 0;
blocks = 0;
blocks_run = 0;
nfile = file;
while (nfile) {
files++;
for (i = 0; i < nfile->n_func; i++) {
func = &nfile->func[i];
funcs++;
for (j = 0; j < func->n_line; j++) {
blocks++;
blocks_run += func->line[j].count != 0;
}
}
nfile = nfile->next;
}
if (blocks == 0)
blocks = 1;
fprintf (fp, " -: 0:All:%s Files:%u Functions:%u %.02f%%\n",
cov_filename, files, funcs, 100.0 * (double) blocks_run / blocks);
nfile = file;
while (nfile) {
FILE *src = fopen (nfile->filename, "r");
unsigned int curline = 1;
char str[10000];
if (src == NULL)
goto next;
funcs = 0;
blocks = 0;
blocks_run = 0;
for (i = 0; i < nfile->n_func; i++) {
func = &nfile->func[i];
funcs++;
for (j = 0; j < func->n_line; j++) {
blocks++;
blocks_run += func->line[j].count != 0;
}
}
if (blocks == 0)
blocks = 1;
fprintf (fp, " -: 0:File:%s Functions:%u %.02f%%\n",
nfile->filename, funcs, 100.0 * (double) blocks_run / blocks);
for (i = 0; i < nfile->n_func; i++) {
func = &nfile->func[i];
while (curline < func->first_line &&
fgets(str, sizeof(str), src))
fprintf (fp, " -:%5u:%s", curline++, str);
blocks = 0;
blocks_run = 0;
for (j = 0; j < func->n_line; j++) {
blocks++;
blocks_run += func->line[j].count != 0;
}
if (blocks == 0)
blocks = 1;
fprintf (fp, " -: 0:Function:%s %.02f%%\n",
func->function, 100.0 * (double) blocks_run / blocks);
#if 0
for (j = 0; j < func->n_line; j++) {
unsigned int fline = func->line[j].fline;
unsigned int lline = func->line[j].lline;
unsigned long long count = func->line[j].count;
fprintf (fp, "%u %u %llu\n", fline, lline, count);
}
#endif
for (j = 0; j < func->n_line;) {
unsigned int fline = func->line[j].fline;
unsigned int lline = func->line[j].lline;
unsigned long long count = func->line[j].count;
unsigned int has_zero = 0;
unsigned int same_line = fline == lline;
j++;
while (j < func->n_line) {
unsigned int nfline = func->line[j].fline;
unsigned int nlline = func->line[j].lline;
unsigned long long ncount = func->line[j].count;
if (fline == nfline) {
if (ncount == 0)
has_zero = 1;
else if (ncount > count)
count = ncount;
same_line = nfline == nlline;
lline = nlline;
j++;
}
else
break;
}
if (same_line)
lline++;
while (curline < fline &&
fgets(str, sizeof(str), src))
fprintf (fp, " -:%5u:%s", curline++, str);
while (curline < lline &&
fgets(str, sizeof(str), src)) {
if (count == 0)
fprintf (fp, " #####:%5u:%s",
curline, str);
else if (has_zero)
fprintf (fp, "%8llu*:%5u:%s",
count, curline, str);
else
fprintf (fp, "%9llu:%5u:%s",
count, curline, str);
curline++;
}
}
}
while (fgets(str, sizeof(str), src))
fprintf (fp, " -:%5u:%s", curline++, str);
fclose (src);
next:
nfile = nfile->next;
}
while (file) {
for (i = 0; i < file->n_func; i++) {
func = &file->func[i];
free (func->line);
}
free (file->func);
nfile = file;
file = file->next;
free (nfile);
}
fclose (fp);
}

67
lib/va_list.c Normal file
View File

@ -0,0 +1,67 @@
/* va_list.c - tinycc support for va_list on X86_64 */
#if defined __x86_64__
/* Avoid include files, they may not be available when cross compiling */
extern void abort(void);
/* This should be in sync with our include/stdarg.h */
enum __va_arg_type {
__va_gen_reg, __va_float_reg, __va_stack
};
/* GCC compatible definition of va_list. */
/*predefined by TCC (tcc_predefs.h):
typedef struct {
unsigned int gp_offset;
unsigned int fp_offset;
union {
unsigned int overflow_offset;
char *overflow_arg_area;
};
char *reg_save_area;
} __builtin_va_list[1];
*/
extern void *memcpy(void *dest, const void *src, unsigned long n);
void *__va_arg(__builtin_va_list ap,
int arg_type,
int size, int align)
{
size = (size + 7) & ~7;
align = (align + 7) & ~7;
switch ((enum __va_arg_type)arg_type) {
case __va_gen_reg:
if (ap->gp_offset + size <= 48) {
ap->gp_offset += size;
return ap->reg_save_area + ap->gp_offset - size;
}
goto use_overflow_area;
case __va_float_reg:
if (ap->fp_offset < 128 + 48) {
ap->fp_offset += 16;
if (size == 8)
return ap->reg_save_area + ap->fp_offset - 16;
if (ap->fp_offset < 128 + 48) {
memcpy(ap->reg_save_area + ap->fp_offset - 8,
ap->reg_save_area + ap->fp_offset, 8);
ap->fp_offset += 16;
return ap->reg_save_area + ap->fp_offset - 32;
}
}
goto use_overflow_area;
case __va_stack:
use_overflow_area:
ap->overflow_arg_area += size;
ap->overflow_arg_area = (char*)((long long)(ap->overflow_arg_area + align - 1) & -align);
return ap->overflow_arg_area - size;
default: /* should never happen */
abort();
return 0;
}
}
#endif

2267
libtcc.c Normal file

File diff suppressed because it is too large Load Diff

100
libtcc.h
View File

@ -1,95 +1,113 @@
#ifndef LIBTCC_H
#define LIBTCC_H
#ifndef LIBTCCAPI
# define LIBTCCAPI
#endif
#ifdef __cplusplus
extern "C" {
#endif
struct TCCState;
/*****************************/
/* set custom allocator for all allocations (optional), NULL for default. */
typedef void *TCCReallocFunc(void *ptr, unsigned long size);
LIBTCCAPI void tcc_set_realloc(TCCReallocFunc *my_realloc);
/*****************************/
typedef struct TCCState TCCState;
/* create a new TCC compilation context */
TCCState *tcc_new(void);
LIBTCCAPI TCCState *tcc_new(void);
/* free a TCC compilation context */
void tcc_delete(TCCState *s);
LIBTCCAPI void tcc_delete(TCCState *s);
/* add debug information in the generated code */
void tcc_enable_debug(TCCState *s);
/* set CONFIG_TCCDIR at runtime */
LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path);
/* set error/warning display callback */
void tcc_set_error_func(TCCState *s, void *error_opaque,
void (*error_func)(void *opaque, const char *msg));
/* set error/warning callback (optional) */
typedef void TCCErrorFunc(void *opaque, const char *msg);
LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc *error_func);
/* set/reset a warning */
int tcc_set_warning(TCCState *s, const char *warning_name, int value);
/* set options as from command line (multiple supported) */
LIBTCCAPI int tcc_set_options(TCCState *s, const char *str);
/*****************************/
/* preprocessor */
/* add include path */
int tcc_add_include_path(TCCState *s, const char *pathname);
LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname);
/* add in system include path */
int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
/* define preprocessor symbol 'sym'. Can put optional value */
void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
/* define preprocessor symbol 'sym'. value can be NULL, sym can be "sym=val" */
LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
/* undefine preprocess symbol 'sym' */
void tcc_undefine_symbol(TCCState *s, const char *sym);
LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym);
/*****************************/
/* compiling */
/* add a file (either a C file, dll, an object, a library or an ld
script). Return -1 if error. */
int tcc_add_file(TCCState *s, const char *filename);
/* add a file (C file, dll, object, library, ld script). Return -1 if error. */
LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename);
/* compile a string containing a C source. Return non zero if
error. */
int tcc_compile_string(TCCState *s, const char *buf);
/* compile a string containing a C source. Return -1 if error. */
LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);
/* Tip: to have more specific errors/warnings from tcc_compile_string(),
you can prefix the string with "#line <num> \"<filename>\"\n" */
/*****************************/
/* linking commands */
/* set output type. MUST BE CALLED before any compilation */
#define TCC_OUTPUT_MEMORY 0 /* output will be ran in memory (no
output file) (default) */
#define TCC_OUTPUT_EXE 1 /* executable file */
#define TCC_OUTPUT_DLL 2 /* dynamic library */
LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);
#define TCC_OUTPUT_MEMORY 1 /* output will be run in memory */
#define TCC_OUTPUT_EXE 2 /* executable file */
#define TCC_OUTPUT_DLL 4 /* dynamic library */
#define TCC_OUTPUT_OBJ 3 /* object file */
#define TCC_OUTPUT_PREPROCESS 4 /* preprocessed file (used internally) */
int tcc_set_output_type(TCCState *s, int output_type);
#define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */
#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
#define TCC_OUTPUT_FORMAT_COFF 2 /* COFF */
#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess */
/* equivalent to -Lpath option */
int tcc_add_library_path(TCCState *s, const char *pathname);
LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);
/* the library name is the same as the argument of the '-l' option */
int tcc_add_library(TCCState *s, const char *libraryname);
LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname);
/* add a symbol to the compiled program */
int tcc_add_symbol(TCCState *s, const char *name, unsigned long val);
LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val);
/* output an executable, library or object file. DO NOT call
tcc_relocate() before. */
int tcc_output_file(TCCState *s, const char *filename);
LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename);
/* link and run main() function and return its value. DO NOT call
tcc_relocate() before. */
int tcc_run(TCCState *s, int argc, char **argv);
LIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv);
/* do all relocations (needed before using tcc_get_symbol()). Return
non zero if link error. */
int tcc_relocate(TCCState *s);
/* do all relocations (needed before using tcc_get_symbol()) */
LIBTCCAPI int tcc_relocate(TCCState *s1);
/* return symbol value. return 0 if OK, -1 if symbol not found */
int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name);
/* return symbol value or NULL if not found */
LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name);
/* list all (global) symbols and their values via 'symbol_cb()' */
LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
void (*symbol_cb)(void *ctx, const char *name, const void *val));
/* experimental/advanced section (see libtcc_test_mt.c for an example) */
/* catch runtime exceptions (optionally limit backtraces at top_func),
when using tcc_set_options("-bt") and when not using tcc_run() */
LIBTCCAPI void *_tcc_setjmp(TCCState *s1, void *jmp_buf, void *top_func, void *longjmp);
#define tcc_setjmp(s1,jb,f) setjmp(_tcc_setjmp(s1, jb, f, longjmp))
/* custom error printer for runtime exceptions. Returning 0 stops backtrace */
typedef int TCCBtFunc(void *udata, void *pc, const char *file, int line, const char* func, const char *msg);
LIBTCCAPI void tcc_set_backtrace_func(TCCState *s1, void* userdata, TCCBtFunc*);
#ifdef __cplusplus
}

View File

@ -1,65 +0,0 @@
/*
* Simple Test program for libtcc
*
* libtcc can be useful to use tcc as a "backend" for a code generator.
*/
#include <stdlib.h>
#include <stdio.h>
#include "libtcc.h"
/* this function is called by the generated code */
int add(int a, int b)
{
return a + b;
}
char my_program[] =
"int fib(int n)\n"
"{\n"
" if (n <= 2)\n"
" return 1;\n"
" else\n"
" return fib(n-1) + fib(n-2);\n"
"}\n"
"\n"
"int foo(int n)\n"
"{\n"
" printf(\"Hello World!\\n\");\n"
" printf(\"fib(%d) = %d\\n\", n, fib(n));\n"
" printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n"
" return 0;\n"
"}\n";
int main(int argc, char **argv)
{
TCCState *s;
int (*func)(int);
unsigned long val;
s = tcc_new();
if (!s) {
fprintf(stderr, "Could not create tcc state\n");
exit(1);
}
/* MUST BE CALLED before any compilation or file loading */
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
tcc_compile_string(s, my_program);
/* as a test, we add a symbol that the compiled program can be
linked with. You can have a similar result by opening a dll
with tcc_add_dll(() and using its symbols directly. */
tcc_add_symbol(s, "add", (unsigned long)&add);
tcc_relocate(s);
tcc_get_symbol(s, &val, "foo");
func = (void *)val;
func(32);
tcc_delete(s);
return 0;
}

3059
riscv64-asm.c Normal file

File diff suppressed because it is too large Load Diff

1496
riscv64-gen.c Normal file

File diff suppressed because it is too large Load Diff

440
riscv64-link.c Normal file
View File

@ -0,0 +1,440 @@
#ifdef TARGET_DEFS_ONLY
#define EM_TCC_TARGET EM_RISCV
#define R_DATA_32 R_RISCV_32
#define R_DATA_PTR R_RISCV_64
#define R_JMP_SLOT R_RISCV_JUMP_SLOT
#define R_GLOB_DAT R_RISCV_64
#define R_COPY R_RISCV_COPY
#define R_RELATIVE R_RISCV_RELATIVE
#define R_NUM R_RISCV_NUM
#define ELF_START_ADDR 0x00010000
#define ELF_PAGE_SIZE 0x1000
#define PCRELATIVE_DLLPLT 1
#define RELOCATE_DLLPLT 1
#else /* !TARGET_DEFS_ONLY */
//#define DEBUG_RELOC
#include "tcc.h"
/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
relocations, returns -1. */
ST_FUNC int code_reloc (int reloc_type)
{
switch (reloc_type) {
case R_RISCV_BRANCH:
case R_RISCV_CALL:
case R_RISCV_JAL:
return 1;
case R_RISCV_GOT_HI20:
case R_RISCV_PCREL_HI20:
case R_RISCV_PCREL_LO12_I:
case R_RISCV_PCREL_LO12_S:
case R_RISCV_32_PCREL:
case R_RISCV_SET6:
case R_RISCV_SET8:
case R_RISCV_SET16:
case R_RISCV_SUB6:
case R_RISCV_ADD16:
case R_RISCV_ADD32:
case R_RISCV_ADD64:
case R_RISCV_SUB8:
case R_RISCV_SUB16:
case R_RISCV_SUB32:
case R_RISCV_SUB64:
case R_RISCV_32:
case R_RISCV_64:
case R_RISCV_SET_ULEB128:
case R_RISCV_SUB_ULEB128:
case R_RISCV_TPREL_HI20:
case R_RISCV_TPREL_LO12_I:
return 0;
case R_RISCV_CALL_PLT:
return 1;
}
return -1;
}
/* Returns an enumerator to describe whether and when the relocation needs a
GOT and/or PLT entry to be created. See tcc.h for a description of the
different values. */
ST_FUNC int gotplt_entry_type (int reloc_type)
{
switch (reloc_type) {
case R_RISCV_ALIGN:
case R_RISCV_RELAX:
case R_RISCV_RVC_BRANCH:
case R_RISCV_RVC_JUMP:
case R_RISCV_JUMP_SLOT:
case R_RISCV_SET6:
case R_RISCV_SET8:
case R_RISCV_SET16:
case R_RISCV_SUB6:
case R_RISCV_ADD16:
case R_RISCV_SUB8:
case R_RISCV_SUB16:
case R_RISCV_SET_ULEB128:
case R_RISCV_SUB_ULEB128:
return NO_GOTPLT_ENTRY;
case R_RISCV_BRANCH:
case R_RISCV_CALL:
case R_RISCV_PCREL_HI20:
case R_RISCV_PCREL_LO12_I:
case R_RISCV_PCREL_LO12_S:
case R_RISCV_32_PCREL:
case R_RISCV_ADD32:
case R_RISCV_ADD64:
case R_RISCV_SUB32:
case R_RISCV_SUB64:
case R_RISCV_32:
case R_RISCV_64:
case R_RISCV_JAL:
case R_RISCV_CALL_PLT:
return AUTO_GOTPLT_ENTRY;
case R_RISCV_GOT_HI20:
return ALWAYS_GOTPLT_ENTRY;
case R_RISCV_TPREL_HI20:
case R_RISCV_TPREL_LO12_I:
return NO_GOTPLT_ENTRY;
}
return -1;
}
ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
{
Section *plt = s1->plt;
uint8_t *p;
unsigned plt_offset;
if (plt->data_offset == 0)
section_ptr_add(plt, 32);
plt_offset = plt->data_offset;
p = section_ptr_add(plt, 16);
write64le(p, got_offset);
return plt_offset;
}
/* relocate the PLT: compute addresses and offsets in the PLT now that final
address for PLT and GOT are known (see fill_program_header) */
ST_FUNC void relocate_plt(TCCState *s1)
{
uint8_t *p, *p_end;
if (!s1->plt)
return;
p = s1->plt->data;
p_end = p + s1->plt->data_offset;
if (p < p_end) {
uint64_t plt = s1->plt->sh_addr;
uint64_t got = s1->got->sh_addr;
uint64_t off = (got - plt + 0x800) >> 12;
if ((off + ((uint32_t)1 << 20)) >> 21)
tcc_error_noabort("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
write32le(p, 0x397 | (off << 12)); // auipc t2, %pcrel_hi(got)
write32le(p + 4, 0x41c30333); // sub t1, t1, t3
write32le(p + 8, 0x0003be03 // ld t3, %pcrel_lo(got)(t2)
| (((got - plt) & 0xfff) << 20));
write32le(p + 12, 0xfd430313); // addi t1, t1, -(32+12)
write32le(p + 16, 0x00038293 // addi t0, t2, %pcrel_lo(got)
| (((got - plt) & 0xfff) << 20));
write32le(p + 20, 0x00135313); // srli t1, t1, log2(16/PTRSIZE)
write32le(p + 24, 0x0082b283); // ld t0, PTRSIZE(t0)
write32le(p + 28, 0x000e0067); // jr t3
p += 32;
while (p < p_end) {
uint64_t pc = plt + (p - s1->plt->data);
uint64_t addr = got + read64le(p);
uint64_t off = (addr - pc + 0x800) >> 12;
if ((off + ((uint32_t)1 << 20)) >> 21)
tcc_error_noabort("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);
write32le(p, 0xe17 | (off << 12)); // auipc t3, %pcrel_hi(func@got)
write32le(p + 4, 0x000e3e03 // ld t3, %pcrel_lo(func@got)(t3)
| (((addr - pc) & 0xfff) << 20));
write32le(p + 8, 0x000e0367); // jalr t1, t3
write32le(p + 12, 0x00000013); // nop
p += 16;
}
}
if (s1->plt->reloc) {
ElfW_Rel *rel;
p = s1->got->data;
for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {
write64le(p + rel->r_offset, s1->plt->sh_addr);
}
}
}
static void riscv64_record_pcrel_hi(TCCState *s1, addr_t addr, addr_t val)
{
struct pcrel_hi *entry = tcc_malloc(sizeof *entry);
entry->addr = addr;
entry->val = val;
dynarray_add(&s1->pcrel_hi_entries, &s1->nb_pcrel_hi_entries, entry);
}
static int riscv64_lookup_pcrel_hi(TCCState *s1, addr_t hi_addr, addr_t *hi_val)
{
int i;
for (i = s1->nb_pcrel_hi_entries; i > 0; ) {
struct pcrel_hi *entry = s1->pcrel_hi_entries[--i];
if (entry->addr == hi_addr) {
*hi_val = entry->val;
return 0;
}
}
return tcc_error_noabort("unsupported hi/lo pcrel reloc scheme");
}
ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
addr_t addr, addr_t val)
{
uint64_t off64;
uint32_t off32;
int sym_index = ELFW(R_SYM)(rel->r_info), esym_index;
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
switch(type) {
case R_RISCV_ALIGN:
case R_RISCV_RELAX:
return;
case R_RISCV_BRANCH:
off64 = val - addr;
if ((off64 + (1 << 12)) & ~(uint64_t)0x1ffe)
tcc_error_noabort("R_RISCV_BRANCH relocation failed"
" (val=%lx, addr=%lx)", (long)val, (long)addr);
off32 = off64 >> 1;
write32le(ptr, (read32le(ptr) & ~0xfe000f80)
| ((off32 & 0x800) << 20)
| ((off32 & 0x3f0) << 21)
| ((off32 & 0x00f) << 8)
| ((off32 & 0x400) >> 3));
return;
case R_RISCV_JAL:
off64 = val - addr;
if ((off64 + (1 << 21)) & ~(((uint64_t)1 << 22) - 2))
tcc_error_noabort("R_RISCV_JAL relocation failed"
" (val=%lx, addr=%lx)", (long)val, (long)addr);
off32 = off64;
write32le(ptr, (read32le(ptr) & 0xfff)
| (((off32 >> 12) & 0xff) << 12)
| (((off32 >> 11) & 1) << 20)
| (((off32 >> 1) & 0x3ff) << 21)
| (((off32 >> 20) & 1) << 31));
return;
case R_RISCV_CALL:
case R_RISCV_CALL_PLT:
write32le(ptr, (read32le(ptr) & 0xfff)
| ((val - addr + 0x800) & ~0xfff));
write32le(ptr + 4, (read32le(ptr + 4) & 0xfffff)
| (((val - addr) & 0xfff) << 20));
return;
case R_RISCV_PCREL_HI20:
#ifdef DEBUG_RELOC
printf("PCREL_HI20: val=%lx addr=%lx\n", (long)val, (long)addr);
#endif
off64 = (int64_t)(val - addr + 0x800) >> 12;
if ((off64 + ((uint64_t)1 << 20)) >> 21)
tcc_error_noabort("R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx sym=%s",
(long)off64, (long)((int64_t)(off64 + ((uint64_t)1 << 20)) >> 21),
symtab_section->link->data + sym->st_name);
write32le(ptr, (read32le(ptr) & 0xfff)
| ((off64 & 0xfffff) << 12));
riscv64_record_pcrel_hi(s1, addr, val);
return;
case R_RISCV_GOT_HI20:
val = s1->got->sh_addr + get_sym_attr(s1, sym_index, 0)->got_offset;
off64 = (int64_t)(val - addr + 0x800) >> 12;
if ((off64 + ((uint64_t)1 << 20)) >> 21)
tcc_error_noabort("R_RISCV_GOT_HI20 relocation failed");
write32le(ptr, (read32le(ptr) & 0xfff)
| ((off64 & 0xfffff) << 12));
riscv64_record_pcrel_hi(s1, addr, val);
return;
case R_RISCV_PCREL_LO12_I:
#ifdef DEBUG_RELOC
printf("PCREL_LO12_I: val=%lx addr=%lx\n", (long)val, (long)addr);
#endif
addr = val;
riscv64_lookup_pcrel_hi(s1, addr, &val);
write32le(ptr, (read32le(ptr) & 0xfffff)
| (((val - addr) & 0xfff) << 20));
return;
case R_RISCV_PCREL_LO12_S:
addr = val;
riscv64_lookup_pcrel_hi(s1, addr, &val);
off32 = val - addr;
write32le(ptr, (read32le(ptr) & ~0xfe000f80)
| ((off32 & 0xfe0) << 20)
| ((off32 & 0x01f) << 7));
return;
case R_RISCV_RVC_BRANCH:
off64 = (val - addr);
if ((off64 + (1 << 8)) & ~(uint64_t)0x1fe)
tcc_error_noabort("R_RISCV_RVC_BRANCH relocation failed"
" (val=%lx, addr=%lx)", (long)val, (long)addr);
off32 = off64;
write16le(ptr, (read16le(ptr) & 0xe383)
| (((off32 >> 5) & 1) << 2)
| (((off32 >> 1) & 3) << 3)
| (((off32 >> 6) & 3) << 5)
| (((off32 >> 3) & 3) << 10)
| (((off32 >> 8) & 1) << 12));
return;
case R_RISCV_RVC_JUMP:
off64 = (val - addr);
if ((off64 + (1 << 11)) & ~(uint64_t)0xffe)
tcc_error_noabort("R_RISCV_RVC_BRANCH relocation failed"
" (val=%lx, addr=%lx)", (long)val, (long)addr);
off32 = off64;
write16le(ptr, (read16le(ptr) & 0xe003)
| (((off32 >> 5) & 1) << 2)
| (((off32 >> 1) & 7) << 3)
| (((off32 >> 7) & 1) << 6)
| (((off32 >> 6) & 1) << 7)
| (((off32 >> 10) & 1) << 8)
| (((off32 >> 8) & 3) << 9)
| (((off32 >> 4) & 1) << 11)
| (((off32 >> 11) & 1) << 12));
return;
case R_RISCV_32:
if (s1->output_type & TCC_OUTPUT_DYN) {
/* XXX: this logic may depend on TCC's codegen
now TCC uses R_RISCV_RELATIVE even for a 64bit pointer */
qrel->r_offset = rel->r_offset;
qrel->r_info = ELFW(R_INFO)(0, R_RISCV_RELATIVE);
/* Use sign extension! */
qrel->r_addend = (int)read32le(ptr) + val;
qrel++;
}
add32le(ptr, val);
return;
case R_RISCV_64:
if (s1->output_type & TCC_OUTPUT_DYN) {
esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
qrel->r_offset = rel->r_offset;
if (esym_index) {
qrel->r_info = ELFW(R_INFO)(esym_index, R_RISCV_64);
qrel->r_addend = rel->r_addend;
qrel++;
break;
} else {
qrel->r_info = ELFW(R_INFO)(0, R_RISCV_RELATIVE);
qrel->r_addend = read64le(ptr) + val;
qrel++;
}
}
case R_RISCV_JUMP_SLOT:
add64le(ptr, val);
return;
case R_RISCV_ADD64:
write64le(ptr, read64le(ptr) + val);
return;
case R_RISCV_ADD32:
write32le(ptr, read32le(ptr) + val);
return;
case R_RISCV_SUB64:
write64le(ptr, read64le(ptr) - val);
return;
case R_RISCV_SUB32:
write32le(ptr, read32le(ptr) - val);
return;
case R_RISCV_ADD16:
write16le(ptr, read16le(ptr) + val);
return;
case R_RISCV_SUB8:
*ptr -= val;
return;
case R_RISCV_SUB16:
write16le(ptr, read16le(ptr) - val);
return;
case R_RISCV_SET6:
*ptr = (*ptr & ~0x3f) | (val & 0x3f);
return;
case R_RISCV_SET8:
*ptr = (*ptr & ~0xff) | (val & 0xff);
return;
case R_RISCV_SET16:
write16le(ptr, val);
return;
case R_RISCV_SUB6:
*ptr = (*ptr & ~0x3f) | ((*ptr - val) & 0x3f);
return;
case R_RISCV_32_PCREL:
if (s1->output_type & TCC_OUTPUT_DYN) {
/* DLL relocation */
esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
if (esym_index) {
qrel->r_offset = rel->r_offset;
qrel->r_info = ELFW(R_INFO)(esym_index, R_RISCV_32_PCREL);
/* Use sign extension! */
qrel->r_addend = (int)read32le(ptr) + rel->r_addend;
qrel++;
break;
}
}
add32le(ptr, val - addr);
return;
case R_RISCV_SET_ULEB128:
case R_RISCV_SUB_ULEB128:
/* ignore. used in section .debug_loclists */
return;
case R_RISCV_COPY:
/* XXX */
return;
case R_RISCV_RELATIVE:
/* R_RISCV_RELATIVE value is already applied in R_RISCV_32/64
dynamic output paths, but we need this case for incoming
RELATIVE relocations from object files. */
return;
case R_RISCV_TPREL_HI20:
case R_RISCV_TPREL_LO12_I: {
addr_t tls_start = 0;
int64_t tp_offset;
int i;
for (i = 1; i < s1->nb_sections; i++) {
Section *s = s1->sections[i];
if (s->sh_flags & SHF_TLS && s->sh_size) {
if (!tls_start || s->sh_addr < tls_start)
tls_start = s->sh_addr;
}
}
tp_offset = val - tls_start;
if (type == R_RISCV_TPREL_HI20) {
off64 = (int64_t)(tp_offset + 0x800) >> 12;
if ((off64 + ((uint64_t)1 << 20)) >> 21)
tcc_error_noabort("R_RISCV_TPREL_HI20 relocation failed");
write32le(ptr, (read32le(ptr) & 0xfff)
| ((off64 & 0xfffff) << 12));
} else {
write32le(ptr, (read32le(ptr) & 0xfffff)
| (((tp_offset) & 0xfff) << 20));
}
return;
}
default:
fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n",
type, (unsigned)addr, ptr, (unsigned)val);
return;
}
}
#endif

612
riscv64-tok.h Normal file
View File

@ -0,0 +1,612 @@
/* ------------------------------------------------------------------ */
/* WARNING: relative order of tokens is important. */
/*
* The specifications are available under https://riscv.org/technical/specifications/
*/
#define DEF_ASM_WITH_SUFFIX(x, y) \
DEF(TOK_ASM_ ## x ## _ ## y, #x "." #y)
#define DEF_ASM_WITH_SUFFIXES(x, y, z) \
DEF(TOK_ASM_ ## x ## _ ## y ## _ ## z, #x "." #y "." #z)
#define DEF_ASM_FENCE(x) \
DEF(TOK_ASM_ ## x ## _fence, #x)
/* register */
/* integer */
DEF_ASM(x0)
DEF_ASM(x1)
DEF_ASM(x2)
DEF_ASM(x3)
DEF_ASM(x4)
DEF_ASM(x5)
DEF_ASM(x6)
DEF_ASM(x7)
DEF_ASM(x8)
DEF_ASM(x9)
DEF_ASM(x10)
DEF_ASM(x11)
DEF_ASM(x12)
DEF_ASM(x13)
DEF_ASM(x14)
DEF_ASM(x15)
DEF_ASM(x16)
DEF_ASM(x17)
DEF_ASM(x18)
DEF_ASM(x19)
DEF_ASM(x20)
DEF_ASM(x21)
DEF_ASM(x22)
DEF_ASM(x23)
DEF_ASM(x24)
DEF_ASM(x25)
DEF_ASM(x26)
DEF_ASM(x27)
DEF_ASM(x28)
DEF_ASM(x29)
DEF_ASM(x30)
DEF_ASM(x31)
/* float */
DEF_ASM(f0)
DEF_ASM(f1)
DEF_ASM(f2)
DEF_ASM(f3)
DEF_ASM(f4)
DEF_ASM(f5)
DEF_ASM(f6)
DEF_ASM(f7)
DEF_ASM(f8)
DEF_ASM(f9)
DEF_ASM(f10)
DEF_ASM(f11)
DEF_ASM(f12)
DEF_ASM(f13)
DEF_ASM(f14)
DEF_ASM(f15)
DEF_ASM(f16)
DEF_ASM(f17)
DEF_ASM(f18)
DEF_ASM(f19)
DEF_ASM(f20)
DEF_ASM(f21)
DEF_ASM(f22)
DEF_ASM(f23)
DEF_ASM(f24)
DEF_ASM(f25)
DEF_ASM(f26)
DEF_ASM(f27)
DEF_ASM(f28)
DEF_ASM(f29)
DEF_ASM(f30)
DEF_ASM(f31)
/* register ABI mnemonics, refer to RISC-V ABI 1.0 */
/* integer */
DEF_ASM(zero)
DEF_ASM(ra)
DEF_ASM(sp)
DEF_ASM(gp)
DEF_ASM(tp)
DEF_ASM(t0)
DEF_ASM(t1)
DEF_ASM(t2)
DEF_ASM(s0)
DEF_ASM(s1)
DEF_ASM(a0)
DEF_ASM(a1)
DEF_ASM(a2)
DEF_ASM(a3)
DEF_ASM(a4)
DEF_ASM(a5)
DEF_ASM(a6)
DEF_ASM(a7)
DEF_ASM(s2)
DEF_ASM(s3)
DEF_ASM(s4)
DEF_ASM(s5)
DEF_ASM(s6)
DEF_ASM(s7)
DEF_ASM(s8)
DEF_ASM(s9)
DEF_ASM(s10)
DEF_ASM(s11)
DEF_ASM(t3)
DEF_ASM(t4)
DEF_ASM(t5)
DEF_ASM(t6)
/* float */
DEF_ASM(ft0)
DEF_ASM(ft1)
DEF_ASM(ft2)
DEF_ASM(ft3)
DEF_ASM(ft4)
DEF_ASM(ft5)
DEF_ASM(ft6)
DEF_ASM(ft7)
DEF_ASM(fs0)
DEF_ASM(fs1)
DEF_ASM(fa0)
DEF_ASM(fa1)
DEF_ASM(fa2)
DEF_ASM(fa3)
DEF_ASM(fa4)
DEF_ASM(fa5)
DEF_ASM(fa6)
DEF_ASM(fa7)
DEF_ASM(fs2)
DEF_ASM(fs3)
DEF_ASM(fs4)
DEF_ASM(fs5)
DEF_ASM(fs6)
DEF_ASM(fs7)
DEF_ASM(fs8)
DEF_ASM(fs9)
DEF_ASM(fs10)
DEF_ASM(fs11)
DEF_ASM(ft8)
DEF_ASM(ft9)
DEF_ASM(ft10)
DEF_ASM(ft11)
/* not in the ABI */
DEF_ASM(pc)
/* Loads */
DEF_ASM(lb)
DEF_ASM(lh)
DEF_ASM(lw)
DEF_ASM(lbu)
DEF_ASM(lhu)
/* RV64 */
DEF_ASM(ld)
DEF_ASM(lwu)
/* Stores */
DEF_ASM(sb)
DEF_ASM(sh)
DEF_ASM(sw)
/* RV64 */
DEF_ASM(sd)
/* Shifts */
DEF_ASM(sll)
DEF_ASM(srl)
DEF_ASM(sra)
/* RV64 */
DEF_ASM(slli)
DEF_ASM(srli)
DEF_ASM(sllw)
DEF_ASM(slliw)
DEF_ASM(srlw)
DEF_ASM(srliw)
DEF_ASM(srai)
DEF_ASM(sraw)
DEF_ASM(sraiw)
/* Arithmetic */
DEF_ASM(add)
DEF_ASM(addi)
DEF_ASM(sub)
DEF_ASM(lui)
DEF_ASM(auipc)
/* RV64 */
DEF_ASM(addw)
DEF_ASM(addiw)
DEF_ASM(subw)
/* Logical */
DEF_ASM(xor)
DEF_ASM(xori)
DEF_ASM(or)
DEF_ASM(ori)
DEF_ASM(and)
DEF_ASM(andi)
/* Compare */
DEF_ASM(slt)
DEF_ASM(slti)
DEF_ASM(sltu)
DEF_ASM(sltiu)
/* Branch */
DEF_ASM(beq)
DEF_ASM(bne)
DEF_ASM(blt)
DEF_ASM(bge)
DEF_ASM(bltu)
DEF_ASM(bgeu)
/* Jump */
DEF_ASM(jal)
DEF_ASM(jalr)
/* Sync */
DEF_ASM(fence)
/* Zifencei extension */
DEF_ASM_WITH_SUFFIX(fence, i)
/* System call */
/* used to be called scall and sbreak */
DEF_ASM(ecall)
DEF_ASM(ebreak)
/* Counters */
DEF_ASM(rdcycle)
DEF_ASM(rdcycleh)
DEF_ASM(rdtime)
DEF_ASM(rdtimeh)
DEF_ASM(rdinstret)
DEF_ASM(rdinstreth)
/* “M” Standard Extension for Integer Multiplication and Division, V2.0 */
DEF_ASM(mul)
DEF_ASM(mulh)
DEF_ASM(mulhsu)
DEF_ASM(mulhu)
DEF_ASM(div)
DEF_ASM(divu)
DEF_ASM(rem)
DEF_ASM(remu)
/* RV64 */
DEF_ASM(mulw)
DEF_ASM(divw)
DEF_ASM(divuw)
DEF_ASM(remw)
DEF_ASM(remuw)
/* "F"/"D" Extension for Single/Double-Precision Floating Point Arithmetic, V2.2 */
/* enough implemented for musl */
DEF_ASM_WITH_SUFFIX(fsgnj, s)
DEF_ASM_WITH_SUFFIX(fsgnj, d)
DEF_ASM_WITH_SUFFIX(fadd, s)
DEF_ASM_WITH_SUFFIX(fadd, d)
DEF_ASM_WITH_SUFFIX(fsub, s)
DEF_ASM_WITH_SUFFIX(fsub, d)
DEF_ASM_WITH_SUFFIX(fmul, s)
DEF_ASM_WITH_SUFFIX(fmul, d)
DEF_ASM_WITH_SUFFIX(fdiv, s)
DEF_ASM_WITH_SUFFIX(fdiv, d)
DEF_ASM_WITH_SUFFIX(fmadd, s)
DEF_ASM_WITH_SUFFIX(fmadd, d)
DEF_ASM_WITH_SUFFIX(fmax, s)
DEF_ASM_WITH_SUFFIX(fmax, d)
DEF_ASM_WITH_SUFFIX(fmin, s)
DEF_ASM_WITH_SUFFIX(fmin, d)
DEF_ASM_WITH_SUFFIX(fsqrt, s)
DEF_ASM_WITH_SUFFIX(fsqrt, d)
/* F/D comparison and conversion (not needed by musl, added for completeness) */
DEF_ASM_WITH_SUFFIX(feq, s)
DEF_ASM_WITH_SUFFIX(feq, d)
DEF_ASM_WITH_SUFFIX(flt, s)
DEF_ASM_WITH_SUFFIX(flt, d)
DEF_ASM_WITH_SUFFIX(fle, s)
DEF_ASM_WITH_SUFFIX(fle, d)
DEF_ASM_WITH_SUFFIX(fclass, s)
DEF_ASM_WITH_SUFFIX(fclass, d)
DEF_ASM_WITH_SUFFIXES(fcvt, w, s)
DEF_ASM_WITH_SUFFIXES(fcvt, wu, s)
DEF_ASM_WITH_SUFFIXES(fcvt, l, s)
DEF_ASM_WITH_SUFFIXES(fcvt, lu, s)
DEF_ASM_WITH_SUFFIXES(fcvt, s, w)
DEF_ASM_WITH_SUFFIXES(fcvt, s, wu)
DEF_ASM_WITH_SUFFIXES(fcvt, s, l)
DEF_ASM_WITH_SUFFIXES(fcvt, s, lu)
DEF_ASM_WITH_SUFFIXES(fcvt, w, d)
DEF_ASM_WITH_SUFFIXES(fcvt, wu, d)
DEF_ASM_WITH_SUFFIXES(fcvt, l, d)
DEF_ASM_WITH_SUFFIXES(fcvt, lu, d)
DEF_ASM_WITH_SUFFIXES(fcvt, d, w)
DEF_ASM_WITH_SUFFIXES(fcvt, d, wu)
DEF_ASM_WITH_SUFFIXES(fcvt, d, l)
DEF_ASM_WITH_SUFFIXES(fcvt, d, lu)
DEF_ASM_WITH_SUFFIXES(fcvt, s, d)
DEF_ASM_WITH_SUFFIXES(fcvt, d, s)
/* "C" Extension for Compressed Instructions, V2.0 */
DEF_ASM_WITH_SUFFIX(c, nop)
/* Loads */
DEF_ASM_WITH_SUFFIX(c, li)
DEF_ASM_WITH_SUFFIX(c, lw)
DEF_ASM_WITH_SUFFIX(c, lwsp)
/* single float */
DEF_ASM_WITH_SUFFIX(c, flw)
DEF_ASM_WITH_SUFFIX(c, flwsp)
/* double float */
DEF_ASM_WITH_SUFFIX(c, fld)
DEF_ASM_WITH_SUFFIX(c, fldsp)
/* RV64 */
DEF_ASM_WITH_SUFFIX(c, ld)
DEF_ASM_WITH_SUFFIX(c, ldsp)
/* Stores */
DEF_ASM_WITH_SUFFIX(c, sw)
DEF_ASM_WITH_SUFFIX(c, sd)
DEF_ASM_WITH_SUFFIX(c, swsp)
DEF_ASM_WITH_SUFFIX(c, sdsp)
/* single float */
DEF_ASM_WITH_SUFFIX(c, fsw)
DEF_ASM_WITH_SUFFIX(c, fswsp)
/* double float */
DEF_ASM_WITH_SUFFIX(c, fsd)
DEF_ASM_WITH_SUFFIX(c, fsdsp)
/* Shifts */
DEF_ASM_WITH_SUFFIX(c, slli)
DEF_ASM_WITH_SUFFIX(c, srli)
DEF_ASM_WITH_SUFFIX(c, srai)
/* Arithmetic */
DEF_ASM_WITH_SUFFIX(c, add)
DEF_ASM_WITH_SUFFIX(c, addi)
DEF_ASM_WITH_SUFFIX(c, addi16sp)
DEF_ASM_WITH_SUFFIX(c, addi4spn)
DEF_ASM_WITH_SUFFIX(c, lui)
DEF_ASM_WITH_SUFFIX(c, sub)
DEF_ASM_WITH_SUFFIX(c, mv)
/* RV64 */
DEF_ASM_WITH_SUFFIX(c, addw)
DEF_ASM_WITH_SUFFIX(c, addiw)
DEF_ASM_WITH_SUFFIX(c, subw)
/* Logical */
DEF_ASM_WITH_SUFFIX(c, xor)
DEF_ASM_WITH_SUFFIX(c, or)
DEF_ASM_WITH_SUFFIX(c, and)
DEF_ASM_WITH_SUFFIX(c, andi)
/* Branch */
DEF_ASM_WITH_SUFFIX(c, beqz)
DEF_ASM_WITH_SUFFIX(c, bnez)
/* Jump */
DEF_ASM_WITH_SUFFIX(c, j)
DEF_ASM_WITH_SUFFIX(c, jr)
DEF_ASM_WITH_SUFFIX(c, jal)
DEF_ASM_WITH_SUFFIX(c, jalr)
/* System call */
DEF_ASM_WITH_SUFFIX(c, ebreak)
/* XXX F Extension: Single-Precision Floating Point */
/* XXX D Extension: Double-Precision Floating Point */
/* from the spec: Tables 16.516.7 list the RVC instructions. */
/* “Zicsr”, Control and Status Register (CSR) Instructions, V2.0 */
DEF_ASM(csrrw)
DEF_ASM(csrrs)
DEF_ASM(csrrc)
DEF_ASM(csrrwi)
DEF_ASM(csrrsi)
DEF_ASM(csrrci)
/* registers */
DEF_ASM(cycle)
DEF_ASM(fcsr)
DEF_ASM(fflags)
DEF_ASM(frm)
DEF_ASM(instret)
DEF_ASM(time)
/* RV32I-only */
DEF_ASM(cycleh)
DEF_ASM(instreth)
DEF_ASM(timeh)
/* pseudo */
DEF_ASM(csrc)
DEF_ASM(csrci)
DEF_ASM(csrr)
DEF_ASM(csrs)
DEF_ASM(csrsi)
DEF_ASM(csrw)
DEF_ASM(csrwi)
DEF_ASM(frcsr)
DEF_ASM(frflags)
DEF_ASM(frrm)
DEF_ASM(fscsr)
DEF_ASM(fsflags)
DEF_ASM(fsrm)
/* Privileged Instructions */
DEF_ASM(mrts)
DEF_ASM(mrth)
DEF_ASM(hrts)
DEF_ASM(wfi)
/* pseudoinstructions */
DEF_ASM(beqz)
DEF_ASM(bgez)
DEF_ASM(bgt)
DEF_ASM(bgtu)
DEF_ASM(bgtz)
DEF_ASM(ble)
DEF_ASM(bleu)
DEF_ASM(blez)
DEF_ASM(bltz)
DEF_ASM(bnez)
DEF_ASM(call)
DEF_ASM_WITH_SUFFIX(fabs, d)
DEF_ASM_WITH_SUFFIX(fabs, s)
DEF_ASM(fld)
DEF_ASM(flw)
DEF_ASM_WITH_SUFFIX(fmv, d)
DEF_ASM_WITH_SUFFIX(fmv, s)
DEF_ASM_WITH_SUFFIX(fneg, d)
DEF_ASM_WITH_SUFFIX(fneg, s)
DEF_ASM(fsd)
DEF_ASM(fsw)
DEF_ASM(j)
DEF_ASM(jump)
DEF_ASM(jr)
DEF_ASM(la)
DEF_ASM(li)
DEF_ASM(lla)
DEF_ASM(mv)
DEF_ASM(neg)
DEF_ASM(negw)
DEF_ASM(nop)
DEF_ASM(not)
DEF_ASM(ret)
DEF_ASM(seqz)
DEF_ASM_WITH_SUFFIX(sext, w)
DEF_ASM(sgtz)
DEF_ASM(sltz)
DEF_ASM(snez)
DEF_ASM(tail)
/* Possible values for .option directive */
DEF_ASM(arch)
DEF_ASM(rvc)
DEF_ASM(norvc)
DEF_ASM(pic)
DEF_ASM(nopic)
DEF_ASM(relax)
DEF_ASM(norelax)
DEF_ASM(push)
DEF_ASM(pop)
/* “A” Standard Extension for Atomic Instructions, Version 2.1 */
/* XXX: Atomic memory operations */
DEF_ASM_WITH_SUFFIX(lr, w)
DEF_ASM_WITH_SUFFIXES(lr, w, aq)
DEF_ASM_WITH_SUFFIXES(lr, w, rl)
DEF_ASM_WITH_SUFFIXES(lr, w, aqrl)
DEF_ASM_WITH_SUFFIX(lr, d)
DEF_ASM_WITH_SUFFIXES(lr, d, aq)
DEF_ASM_WITH_SUFFIXES(lr, d, rl)
DEF_ASM_WITH_SUFFIXES(lr, d, aqrl)
DEF_ASM_WITH_SUFFIX(sc, w)
DEF_ASM_WITH_SUFFIXES(sc, w, aq)
DEF_ASM_WITH_SUFFIXES(sc, w, rl)
DEF_ASM_WITH_SUFFIXES(sc, w, aqrl)
DEF_ASM_WITH_SUFFIX(sc, d)
DEF_ASM_WITH_SUFFIXES(sc, d, aq)
DEF_ASM_WITH_SUFFIXES(sc, d, rl)
DEF_ASM_WITH_SUFFIXES(sc, d, aqrl)
/* "A" Extension for Atomic Operations, V2.1 (base, no aq/rl suffixes) */
DEF_ASM_WITH_SUFFIX(amoadd, w)
DEF_ASM_WITH_SUFFIX(amoadd, d)
DEF_ASM_WITH_SUFFIX(amoswap, w)
DEF_ASM_WITH_SUFFIX(amoswap, d)
DEF_ASM_WITH_SUFFIX(amoand, w)
DEF_ASM_WITH_SUFFIX(amoand, d)
DEF_ASM_WITH_SUFFIX(amoor, w)
DEF_ASM_WITH_SUFFIX(amoor, d)
DEF_ASM_WITH_SUFFIX(amoxor, w)
DEF_ASM_WITH_SUFFIX(amoxor, d)
DEF_ASM_WITH_SUFFIX(amomax, w)
DEF_ASM_WITH_SUFFIX(amomax, d)
DEF_ASM_WITH_SUFFIX(amomaxu, w)
DEF_ASM_WITH_SUFFIX(amomaxu, d)
DEF_ASM_WITH_SUFFIX(amomin, w)
DEF_ASM_WITH_SUFFIX(amomin, d)
DEF_ASM_WITH_SUFFIX(amominu, w)
DEF_ASM_WITH_SUFFIX(amominu, d)
/* AMO aq/rl ordering suffixes */
DEF_ASM_WITH_SUFFIXES(amoadd, w, aq)
DEF_ASM_WITH_SUFFIXES(amoadd, w, rl)
DEF_ASM_WITH_SUFFIXES(amoadd, w, aqrl)
DEF_ASM_WITH_SUFFIXES(amoadd, d, aq)
DEF_ASM_WITH_SUFFIXES(amoadd, d, rl)
DEF_ASM_WITH_SUFFIXES(amoadd, d, aqrl)
/* Complete AMO aq/rl ordering suffixes (all ops) */
DEF_ASM_WITH_SUFFIXES(amoswap, w, aq)
DEF_ASM_WITH_SUFFIXES(amoswap, w, rl)
DEF_ASM_WITH_SUFFIXES(amoswap, w, aqrl)
DEF_ASM_WITH_SUFFIXES(amoswap, d, aq)
DEF_ASM_WITH_SUFFIXES(amoswap, d, rl)
DEF_ASM_WITH_SUFFIXES(amoswap, d, aqrl)
DEF_ASM_WITH_SUFFIXES(amoand, w, aq)
DEF_ASM_WITH_SUFFIXES(amoand, w, rl)
DEF_ASM_WITH_SUFFIXES(amoand, w, aqrl)
DEF_ASM_WITH_SUFFIXES(amoand, d, aq)
DEF_ASM_WITH_SUFFIXES(amoand, d, rl)
DEF_ASM_WITH_SUFFIXES(amoand, d, aqrl)
DEF_ASM_WITH_SUFFIXES(amoor, w, aq)
DEF_ASM_WITH_SUFFIXES(amoor, w, rl)
DEF_ASM_WITH_SUFFIXES(amoor, w, aqrl)
DEF_ASM_WITH_SUFFIXES(amoor, d, aq)
DEF_ASM_WITH_SUFFIXES(amoor, d, rl)
DEF_ASM_WITH_SUFFIXES(amoor, d, aqrl)
DEF_ASM_WITH_SUFFIXES(amoxor, w, aq)
DEF_ASM_WITH_SUFFIXES(amoxor, w, rl)
DEF_ASM_WITH_SUFFIXES(amoxor, w, aqrl)
DEF_ASM_WITH_SUFFIXES(amoxor, d, aq)
DEF_ASM_WITH_SUFFIXES(amoxor, d, rl)
DEF_ASM_WITH_SUFFIXES(amoxor, d, aqrl)
DEF_ASM_WITH_SUFFIXES(amomax, w, aq)
DEF_ASM_WITH_SUFFIXES(amomax, w, rl)
DEF_ASM_WITH_SUFFIXES(amomax, w, aqrl)
DEF_ASM_WITH_SUFFIXES(amomax, d, aq)
DEF_ASM_WITH_SUFFIXES(amomax, d, rl)
DEF_ASM_WITH_SUFFIXES(amomax, d, aqrl)
DEF_ASM_WITH_SUFFIXES(amomaxu, w, aq)
DEF_ASM_WITH_SUFFIXES(amomaxu, w, rl)
DEF_ASM_WITH_SUFFIXES(amomaxu, w, aqrl)
DEF_ASM_WITH_SUFFIXES(amomaxu, d, aq)
DEF_ASM_WITH_SUFFIXES(amomaxu, d, rl)
DEF_ASM_WITH_SUFFIXES(amomaxu, d, aqrl)
DEF_ASM_WITH_SUFFIXES(amomin, w, aq)
DEF_ASM_WITH_SUFFIXES(amomin, w, rl)
DEF_ASM_WITH_SUFFIXES(amomin, w, aqrl)
DEF_ASM_WITH_SUFFIXES(amomin, d, aq)
DEF_ASM_WITH_SUFFIXES(amomin, d, rl)
DEF_ASM_WITH_SUFFIXES(amomin, d, aqrl)
DEF_ASM_WITH_SUFFIXES(amominu, w, aq)
DEF_ASM_WITH_SUFFIXES(amominu, w, rl)
DEF_ASM_WITH_SUFFIXES(amominu, w, aqrl)
DEF_ASM_WITH_SUFFIXES(amominu, d, aq)
DEF_ASM_WITH_SUFFIXES(amominu, d, rl)
DEF_ASM_WITH_SUFFIXES(amominu, d, aqrl)
/* rounding mode keywords (used as fcvt operand: fcvt.w.s rd, rs1, rtz) */
DEF_ASM(rne)
DEF_ASM(rtz)
DEF_ASM(rdn)
DEF_ASM(rup)
DEF_ASM(rmm)
/* `fence` arguments */
/* NOTE: Order is important */
DEF_ASM_FENCE(w)
DEF_ASM_FENCE(r)
DEF_ASM_FENCE(rw)
DEF_ASM_FENCE(o)
DEF_ASM_FENCE(ow)
DEF_ASM_FENCE(or)
DEF_ASM_FENCE(orw)
DEF_ASM_FENCE(i)
DEF_ASM_FENCE(iw)
DEF_ASM_FENCE(ir)
DEF_ASM_FENCE(irw)
DEF_ASM_FENCE(io)
DEF_ASM_FENCE(iow)
DEF_ASM_FENCE(ior)
DEF_ASM_FENCE(iorw)
#undef DEF_ASM_FENCE
#undef DEF_ASM_WITH_SUFFIX
#undef DEF_ASM_WITH_SUFFIXES

View File

@ -1,16 +0,0 @@
#ifndef _STDARG_H
#define _STDARG_H
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)
/* fix a buggy dependency on GCC in libio.h */
typedef va_list __gnuc_va_list;
#define _VA_LIST_DEFINED
#endif

View File

@ -1,26 +0,0 @@
#ifndef _STDDEF_H
#define _STDDEF_H
#define NULL ((void *)0)
typedef __SIZE_TYPE__ size_t;
typedef __WCHAR_TYPE__ wchar_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#define offsetof(type, field) ((size_t) &((type *)0)->field)
/* need to do that because of glibc 2.1 bug (should have a way to test
presence of 'long long' without __GNUC__, or TCC should define
__GNUC__ ? */
#if !defined(__int8_t_defined) && !defined(__dietlibc__)
#define __int8_t_defined
typedef char int8_t;
typedef short int int16_t;
typedef int int32_t;
typedef long long int int64_t;
#endif
#ifdef __i386__
void *_alloca(size_t);
#define alloca _alloca
#endif
#endif

View File

@ -2,6 +2,10 @@
@c %**start of header
@setfilename tcc-doc.info
@settitle Tiny C Compiler Reference Documentation
@dircategory Software development
@direntry
* TCC: (tcc-doc). The Tiny C Compiler.
@end direntry
@c %**end of header
@include config.texi
@ -16,11 +20,8 @@
@headings double
@end iftex
@c @ifhtml
@contents
@c @end ifhtml
@ifnothtml
@node Top, Introduction, (dir), (dir)
@top Tiny C Compiler Reference Documentation
@ -29,10 +30,14 @@ This manual documents version @value{VERSION} of the Tiny C Compiler.
@menu
* Introduction:: Introduction to tcc.
* Invoke:: Invocation of tcc (command line, options).
* Clang:: ANSI C and extensions.
* asm:: Assembler syntax.
* linker:: Output file generation and supported targets.
* Bounds:: Automatic bounds-checking of C code.
* Libtcc:: The libtcc library.
* devel:: Guide for Developers.
@end menu
@end ifnothtml
@node Introduction
@chapter Introduction
@ -42,7 +47,7 @@ compilers, it is meant to be self-relying: you do not need an
external assembler or linker because TCC does that for you.
TCC compiles so @emph{fast} that even for big projects @code{Makefile}s may
not be necessary.
not be necessary.
TCC not only supports ANSI C, but also most of the new ISO C99
standard and many GNUC extensions including inline assembly.
@ -63,11 +68,11 @@ ports for the ARM (@code{arm-tcc}) and the TMS320C67xx targets
(@code{c67-tcc}). More information about the ARM port is available at
@url{http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html}.
For usage on Windows, see also @url{tcc-win32.txt}.
@node Invoke
@chapter Command line invocation
[This manual documents version @value{VERSION} of the Tiny C Compiler]
@section Quick start
@example
@ -78,7 +83,7 @@ usage: tcc [options] [@var{infile1} @var{infile2}@dots{}] [@option{-run} @var{in
@noindent
@c man begin DESCRIPTION
TCC options are a very much like gcc options. The main difference is that TCC
TCC options are very much like gcc options. The main difference is that TCC
can also execute directly the resulting program and give it runtime
arguments.
@ -142,7 +147,7 @@ TCC can read C source code from @emph{standard input} when @option{-} is used in
place of @option{infile}. Example:
@example
echo 'main(){puts("hello");}' | tcc -run -
echo 'main()@{puts("hello");@}' | tcc -run -
@end example
@c man end
@ -152,43 +157,34 @@ General Options:
@c man begin OPTIONS
@table @option
@item -v
Display current TCC version, increase verbosity.
@item -c
Generate an object file (@option{-o} option must also be given).
Generate an object file.
@item -o outfile
Put object file, executable, or dll into output file @file{outfile}.
@item -Bdir
Set the path where the tcc internal libraries can be found (default is
@file{PREFIX/lib/tcc}).
@item -bench
Output compilation statistics.
@item -run source [args...]
Compile file @var{source} and run it with the command line arguments
@var{args}. In order to be able to give more than one argument to a
script, several TCC options can be given @emph{after} the
@option{-run} option, separated by spaces. Example:
@option{-run} option, separated by spaces:
@example
tcc "-run -L/usr/X11R6/lib -lX11" ex4.c
@end example
In a script, it gives the following header:
@example
#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
#include <stdlib.h>
int main(int argc, char **argv)
@{
...
@}
@end example
@item -v
Display TCC version.
@item -vv
Show included files. As sole argument, print search dirs. -vvv shows tries too.
@item -bench
Display compilation statistics.
@end table
Preprocessor options:
@ -203,6 +199,16 @@ include paths are: @file{/usr/local/include}, @file{/usr/include}
and @file{PREFIX/lib/tcc/include}. (@file{PREFIX} is usually
@file{/usr} or @file{/usr/local}).
@item -isystem dir
Specify a system include path to be added to the defaults.
@item -nostdinc
Do not search the default system include paths; only search include paths
provided on the command line.
@item -include file
Include @option{file} above each input file.
@item -Dsym[=val]
Define preprocessor symbol @samp{sym} to
val. If val is not present, its value is @samp{1}. Function-like macros can
@ -210,11 +216,27 @@ also be defined: @option{-DF(a)=a+1}
@item -Usym
Undefine preprocessor symbol @samp{sym}.
@item -E
Preprocess only, to stdout or file (with -o).
@item -P
Do not output @code{#line} directives.
@item -P1
Output alternative @code{#line} directives.
@item -dD, -dM
Output @code{#define} directives.
@item -Wp,-opt
Same as @option{-opt}.
@end table
Compilation flags:
Note: each of the following warning options has a negative form beginning with
Note: each of the following options has a negative form beginning with
@option{-fno-}.
@table @option
@ -230,6 +252,27 @@ Do not generate common symbols for uninitialized data.
@item -fleading-underscore
Add a leading underscore at the beginning of each C symbol.
@item -fms-extensions
Allow a MS C compiler extensions to the language. Currently this
assumes a nested named structure declaration without an identifier
behaves like an unnamed one.
@item -fdollars-in-identifiers
Allow dollar signs in identifiers
@item -freverse-funcargs
Evaluate function arguments right to left.
@item -fgnu89-inline
@code{extern inline} is like @code{static inline}.
@item -fasynchronous-unwind-tables
Create eh_frame section [on]
@item -ftest-coverage
Create code coverage code. After running the resulting code an executable.tcov
or sofile.tcov file is generated with code coverage.
@end table
Warning options:
@ -245,7 +288,10 @@ Note: each of the following warning options has a negative form beginning with
@table @option
@item -Wimplicit-function-declaration
Warn about implicit function declaration.
Warn about implicit function declaration (missing prototype).
@item -Wdiscarded-qualifiers
Warn when const is dropped.
@item -Wunsupported
Warn about unsupported GCC features that are ignored by TCC.
@ -255,11 +301,13 @@ Make string constants be of type @code{const char *} instead of @code{char
*}.
@item -Werror
Abort compilation if warnings are issued.
Abort compilation if a warning is issued. Can be given an option to enable
the specified warning and turn it into an error, for example
@option{-Werror=unsupported}.
@item -Wall
Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and
@option{-Wwrite-strings}.
Activate some useful warnings (@option{-Wimplicit-function-declaration},
@option{-Wdiscard-qualifiers}).
@end table
@ -273,28 +321,50 @@ default library paths are @file{/usr/local/lib}, @file{/usr/lib} and @file{/lib}
@item -lxxx
Link your program with dynamic library libxxx.so or static library
libxxx.a. The library is searched in the paths specified by the
@option{-L} option.
@option{-L} option and @env{LIBRARY_PATH} variable.
@item -Bdir
Set the path where the tcc internal libraries (and include files) can be
found (default is @file{PREFIX/lib/tcc}).
@item -shared
Generate a shared library instead of an executable (@option{-o} option
must also be given).
Generate a shared library instead of an executable.
@item -soname name
set name for shared library to be used at runtime
@item -static
Generate a statically linked executable (default is a shared linked
executable) (@option{-o} option must also be given).
executable).
@item -rdynamic
Export global symbols to the dynamic linker. It is useful when a library
opened with @code{dlopen()} needs to access executable symbols.
@item -r
Generate an object file combining all input files (@option{-o} option must
also be given).
Generate an object file combining all input files.
@item -Wl,-Ttext,address
Set the start of the .text section to @var{address}.
@item -nostdlib
Don't implicitly link with libc, the C runtime files, and libtcc1.
@item -Wl,--oformat,fmt
@item -Wl,-nostdlib
Don't search the default paths for libraries (@file{/usr/local/lib},
@file{/usr/lib} and @file{/lib}). Only the paths specified with @option{-L}
and @env{LIBRARY_PATH} are searched.
@item -Wl,-rpath=path
Put custom search path for dynamic libraries into executable.
@item -Wl,-Ipath
@item -Wl,--dynamic-linker=path
Set the ELF interpreter (dynamic linker). This defaults to the value of the
environment variable @env{LD_SO} if set, or a compiled-in default.
@item -Wl,--enable-new-dtags
When putting a custom search path for dynamic libraries into the executable,
create the new ELF dynamic tag DT_RUNPATH instead of the old legacy DT_RPATH.
@item -Wl,--oformat=fmt
Use @var{fmt} as output format. The supported output formats are:
@table @code
@item elf32-i386
@ -305,30 +375,144 @@ Binary image (only for executable output)
COFF output format (only for executable output for TMS320C67xx target)
@end table
@item -Wl,--export-all-symbols
@item -Wl,--export-dynamic
Export global symbols to the dynamic linker. It is useful when a library
opened with @code{dlopen()} needs to access executable symbols.
@item -Wl,-subsystem=console/gui/wince/...
Set type for PE (Windows) executables.
@item -Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]
Modify executable layout.
@item -Wl,-[dynamicbase | nxcompat | high-entropy-va | tsaware]
@item -Wl,-[no-dynamicbase | no-nxcompat | no-high-entropy-va | no-tsaware]
@item -Wl,-[disable-dynamicbase | disable-nxcompat | disable-high-entropy-va | disable-tsaware]
Set or clear PE (Windows) executable header hardening flags. The
@option{-Wl,-high-entropy-va} option is supported on x86-64 and ARM64 PE
targets and implies @option{-Wl,-dynamicbase}. Clearing dynamicbase also
clears high-entropy-va. When @option{-Wl,-dynamicbase} is used for an
executable, TCC also enables base relocation emission for Windows ASLR.
@item -Wl,-Bsymbolic
Set DT_SYMBOLIC tag.
@item -Wl,-(no-)whole-archive
Turn on/off linking of all objects in archives.
@end table
Debugger options:
@table @option
@item -g
Generate run time debug information so that you get clear run time
Generate run time stab debug information so that you get clear run time
error messages: @code{ test.c:68: in function 'test5()': dereferencing
invalid pointer} instead of the laconic @code{Segmentation
fault}.
@item -b
Generate additional support code to check
memory allocations and array/pointer bounds. @option{-g} is implied. Note
that the generated code is slower and bigger in this case.
@item -gdwarf[-x]
Generate run time dwarf debug information instead of stab debug information.
@item -bt N
Display N callers in stack traces. This is useful with @option{-g} or
@option{-b}.
@item -b
Generate additional support code to check memory allocations and array/pointer
bounds (@pxref{Bounds}). @option{-g} is implied.
@item -bt[N]
Display N callers in stack traces. This is useful with @option{-g} or @option{-b}.
When activated, @code{__TCC_BACKTRACE__} is defined.
With executables, additional support for stack traces is included. A function
@code{ int tcc_backtrace(const char *fmt, ...); }
is provided to trigger a stack trace with a message on demand.
@end table
Misc options:
@table @option
@item -std=version
Define @code{__STDC_VERSION__}: @code{201112} if @option{version} is c11 or
gnu11; @code{199901} otherwise.
@item -x[c|a|b|n]
Specify content of next input file: respectively C, assembly, binary, or none.
@item -O[n]
Same as @option{-D__OPTIMIZE__} except for -O0.
@item -pthread
Preprocess with @option{-D_REENTRANT}, link with @option{-lpthread}.
@item -M
Just output makefile fragment with dependencies
@item -MM
Like -M except mention only user header files, not system header files.
@item -MD
Generate makefile fragment with dependencies.
@item -MMD
Like -MD except mention only user header files, not system header files.
@item -MF depfile
Use @file{depfile} as output for -MD.
@item -MP
Mention all dependencies as targets too.
@item -print-search-dirs
Print the configured installation directory and a list of library
and include directories tcc will search.
@item -dumpversion
Print version.
@item -dt
With @option{-run}/@option{-E}: auto-define 'test_...' macros
@end table
Target specific options:
@table @option
@item -mms-bitfields
Use an algorithm for bitfield alignment consistent with MSVC. Default is
gcc's algorithm.
@item -mfloat-abi (ARM only)
Select the float ABI. Possible values: @code{softfp} and @code{hard}
@item -mno-sse
Do not use sse registers on x86_64
@item -m32, -m64
Pass command line to the i386/x86_64 cross compiler.
@end table
Note: GCC options @option{-fx} and @option{-mx} are ignored.
@c man end
@c man begin ENVIRONMENT
Environment variables that affect how tcc operates.
@table @option
@item CPATH
@item C_INCLUDE_PATH
A colon-separated list of directories searched for include files,
directories given with @option{-I} are searched first.
@item LIBRARY_PATH
A colon-separated list of directories searched for libraries for the
@option{-l} option, directories given with @option{-L} are searched first.
@end table
Note: GCC options @option{-Ox}, @option{-fx} and @option{-mx} are
ignored.
@c man end
@ignore
@ -337,6 +521,7 @@ ignored.
@settitle Tiny C Compiler
@c man begin SEEALSO
cpp(1),
gcc(1)
@c man end
@ -346,6 +531,7 @@ Fabrice Bellard
@end ignore
@node Clang
@chapter C language support
@section ANSI C
@ -357,13 +543,14 @@ and floating point numbers (@code{long double}, @code{double}, and
@section ISOC99 extensions
TCC implements many features of the new C standard: ISO C99. Currently
missing items are: complex and imaginary numbers and variable length
arrays.
missing items are: complex and imaginary numbers.
Currently implemented ISOC99 features:
@itemize
@item variable length arrays.
@item 64 bit @code{long long} types are fully supported.
@item The boolean type @code{_Bool} is supported.
@ -455,6 +642,7 @@ instead of
@cindex stdcall attribute
@cindex regparm attribute
@cindex dllexport attribute
@cindex nodecorate attribute
@item The keyword @code{__attribute__} is handled to specify variable or
function attributes. The following attributes are supported:
@ -482,6 +670,8 @@ registers @code{%eax}, @code{%edx} and @code{%ecx}.
@item @code{dllexport}: export function from dll/executable (win32 only)
@item @code{nodecorate}: do not apply any decorations that would otherwise be applied when exporting function from dll/executable (win32 only)
@end itemize
Here are some examples:
@ -565,23 +755,21 @@ are supported.
@itemize
@item @code{__TINYC__} is a predefined macro to @code{1} to
indicate that you use TCC.
@item @code{__TINYC__} is a predefined macro to indicate that you use TCC.
@item @code{#!} at the start of a line is ignored to allow scripting.
@item Binary digits can be entered (@code{0b101} instead of
@code{5}).
@item @code{__BOUNDS_CHECKING_ON} is defined if bound checking is activated.
@end itemize
@node asm
@chapter TinyCC Assembler
Since version 0.9.16, TinyCC integrates its own assembler. TinyCC
assembler supports a gas-like syntax (GNU assembler). You can
desactivate assembler support if you want a smaller TinyCC executable
deactivate assembler support if you want a smaller TinyCC executable
(the C compiler does not rely on the assembler).
TinyCC Assembler is used to handle files with @file{.S} (C
@ -670,7 +858,7 @@ They can be defined several times in the same source. Use 'b'
@cindex asciz directive
@cindex ascii directive
All directives are preceeded by a '.'. The following directives are
All directives are preceded by a '.'. The following directives are
supported:
@itemize
@ -706,6 +894,7 @@ tries to guess it from the operand sizes.
Currently, MMX opcodes are supported but not SSE ones.
@node linker
@chapter TinyCC Linker
@cindex linker
@ -733,17 +922,10 @@ libraries (.so).
@section PE-i386 file generation
@cindex PE-i386
TCC for Windows supports the native Win32 executable file format (PE-i386). It
generates both EXE and DLL files. DLL symbols can be imported thru DEF files
generated with the @code{tiny_impdef} tool.
TCC for Windows supports the native Win32 executable file format (PE-i386). It
generates EXE files (console and gui) and DLL files.
On the object file level, currently TCC supports only the ELF format, not COFF
as used by MINGW and MSVC. It is not possible to exchange object files or
libraries between TCC and these compilers. However libraries for TCC from objects
by TCC can be made using the @code{tiny_libmaker} tool or MINGW's @code{ar}.
No leading underscore is generated in the ELF symbols. Only functions (no
data) can be exported. Bounds checking (@option{-b}) is not supported currently.
For usage on Windows, see also tcc-win32.txt.
@section GNU Linker Scripts
@cindex scripts, linker
@ -773,16 +955,7 @@ GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a )
@cindex bound checks
@cindex memory checks
This feature is activated with the @option{-b} (@pxref{Invoke}).
Note that pointer size is @emph{unchanged} and that code generated
with bound checks is @emph{fully compatible} with unchecked
code. When a pointer comes from unchecked code, it is assumed to be
valid. Even very obscure C code with casts should work correctly.
For more information about the ideas behind this method, see
@url{http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html}.
This feature is activated with the @option{-b} option (@pxref{Invoke}).
Here are some examples of caught errors:
@table @asis
@ -811,7 +984,7 @@ Here are some examples of caught errors:
int *tab;
tab = malloc(20 * sizeof(int));
for(i=0;i<21;i++) @{
sum += tab4[i];
sum += tab[i];
@}
free(tab);
@}
@ -824,7 +997,7 @@ Here are some examples of caught errors:
tab = malloc(20 * sizeof(int));
free(tab);
for(i=0;i<20;i++) @{
sum += tab4[i];
sum += tab[i];
@}
@}
@end example
@ -838,9 +1011,68 @@ Here are some examples of caught errors:
free(tab);
@}
@end example
@end table
TCC defines @code{__TCC_BCHECK__} if activated.
There are five environment variables that can be used to control the behavior:
@itemize
@item TCC_BOUNDS_WARN_POINTER_ADD
- Print warning when pointer add creates an illegal pointer.
@item TCC_BOUNDS_PRINT_CALLS
- Print bound checking calls. Can be used for debugging.
@item TCC_BOUNDS_PRINT_HEAP
- Print heap objects that are not freed at exit of program.
@item TCC_BOUNDS_PRINT_STATISTIC
- Print statistic information at exit of program.
@item TCC_BOUNDS_NEVER_FATAL
- Try to continue in case of a bound checking error.
@end itemize
Also, a function @code{__bounds_checking(x)} can be used to turn off/on bounds
checking from usercode (see below).
Notes:
@itemize
@item Only available on i386 (linux and windows), x86_64 (linux and windows),
arm, arm64 and riscv64 for the moment.
@item The generated code is slower and bigger.
@item The bound checking code is not included in shared libraries. The main
executable should always be compiled with the @option{-b}.
@item Pointer size is @emph{unchanged} and code generated with bound checks is
@emph{fully compatible} with unchecked code. When a pointer comes from
unchecked code, it is assumed to be valid. Even very obscure C code with
casts should work correctly.
@item Signal handlers are not compatible with bounds checking. The
bounds checking code disables checking in signal/sigaction handlers.
The fork() function call in a multi threaded application is also a problem.
The bound checking code fixes this for the child process.
@item The reason that signals and fork have problems is that we use locking
inside the bounds checking code.
Inside a signal handler we can not use locks. Also in a multi threaded
application after a fork the child process can have the lock set
by another thread.
@item The BOUNDS_CHECKING_OFF and BOUNDS_CHECKING_ON can also be used to
disable bounds checking for some code.
@item The __bounds_checking call adds a value to a thread local value.
The value starts at 0. If the value is not 0 the code is not checked
for bounds checking errors.
@end itemize
@example
#ifdef __TCC_BCHECK__
extern void __bounds_checking (int x);
# define BOUNDS_CHECKING_OFF __bounds_checking(1)
# define BOUNDS_CHECKING_ON __bounds_checking(-1)
#else
# define BOUNDS_CHECKING_OFF
# define BOUNDS_CHECKING_ON
#endif
@end example
For more information about the ideas behind this method, see
@url{http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html}.
@node Libtcc
@chapter The @code{libtcc} library
@ -854,6 +1086,7 @@ The idea consists in giving a C string containing the program you want
to compile directly to @code{libtcc}. Then you can access to any global
symbol (function or variable) defined.
@node devel
@chapter Developer's guide
This chapter gives some hints to understand how TCC works. You can skip
@ -894,7 +1127,7 @@ reverse order, a first pass is done to reverse the argument order.
@section Types
The types are stored in a single 'int' variable. It was choosen in the
The types are stored in a single 'int' variable. It was chosen in the
first stages of development when tcc was much simpler. Now, it may not
be the best solution.
@ -917,9 +1150,13 @@ be the best solution.
#define VT_BTYPE 0x000f /* mask for basic type */
#define VT_UNSIGNED 0x0010 /* unsigned type */
#define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
#define VT_VLA 0x20000 /* VLA type (also has VT_PTR and VT_ARRAY) */
#define VT_BITFIELD 0x0040 /* bitfield modifier */
#define VT_CONSTANT 0x0800 /* const modifier */
#define VT_VOLATILE 0x1000 /* volatile modifier */
#define VT_DEFSIGN 0x2000 /* signed type */
#define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
#define VT_STRUCT_SHIFT 18 /* structure/enum name shift (14 bits left) */
@end example
When a reference to another type is needed (for pointers, functions and
@ -930,7 +1167,8 @@ The @code{VT_UNSIGNED} flag can be set for chars, shorts, ints and long
longs.
Arrays are considered as pointers @code{VT_PTR} with the flag
@code{VT_ARRAY} set.
@code{VT_ARRAY} set. Variable length arrays are considered as special
arrays and have flag @code{VT_VLA} set instead of @code{VT_ARRAY}.
The @code{VT_BITFIELD} flag can be set for chars, shorts, ints and long
longs. If it is set, then the bitfield position is stored from bits
@ -946,6 +1184,10 @@ integer:
#define VT_EXTERN 0x00000080 /* extern definition */
#define VT_STATIC 0x00000100 /* static variable */
#define VT_TYPEDEF 0x00000200 /* typedef definition */
#define VT_INLINE 0x00000400 /* inline definition */
#define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */
#define VT_EXPORT 0x00008000 /* win32: data exported from dll */
#define VT_WEAK 0x00010000 /* win32: data exported from dll */
@end example
@section Symbols
@ -954,10 +1196,13 @@ All symbols are stored in hashed symbol stacks. Each symbol stack
contains @code{Sym} structures.
@code{Sym.v} contains the symbol name (remember
an idenfier is also a token, so a string is never necessary to store
an identifier is also a token, so a string is never necessary to store
it). @code{Sym.t} gives the type of the symbol. @code{Sym.r} is usually
the register in which the corresponding variable is stored. @code{Sym.c} is
usually a constant associated to the symbol.
usually a constant associated to the symbol like its address for normal
symbols, and the number of entries for symbols representing arrays.
Variable length array types use @code{Sym.c} as a location on the stack
which holds the runtime sizeof for the type.
Four main symbol stacks are defined:
@ -994,7 +1239,7 @@ global stack.
@section Sections
The generated code and datas are written in sections. The structure
The generated code and data are written in sections. The structure
@code{Section} contains all the necessary information for a given
section. @code{new_section()} creates a new section. ELF file semantics
is assumed for each section.
@ -1019,7 +1264,7 @@ are used when bound checking is activated
@item stab_section
@itemx stabstr_section
are used when debugging is actived to store debug information
are used when debugging is active to store debug information
@item symtab_section
@itemx strtab_section
@ -1119,8 +1364,10 @@ if the lvalue has an integer type, then these flags give its real
type. The type alone is not enough in case of cast optimisations.
@item VT_LLOCAL
is a saved lvalue on the stack. @code{VT_LLOCAL} should be eliminated
ASAP because its semantics are rather complicated.
is a saved lvalue on the stack. @code{VT_LVAL} must also be set with
@code{VT_LLOCAL}. @code{VT_LLOCAL} can arise when a @code{VT_LVAL} in
a register has to be saved to the stack, or it can come from an
architecture-specific calling convention.
@item VT_MUSTCAST
indicates that a cast to the value type must be performed if the value
@ -1179,13 +1426,13 @@ should generate a function prolog/epilog.
@item gen_opi(op)
must generate the binary integer operation @var{op} on the two top
entries of the stack which are guaranted to contain integer types.
entries of the stack which are guaranteed to contain integer types.
The result value should be put on the stack.
@item gen_opf(op)
same as @code{gen_opi()} for floating point operations. The two top
entries of the stack are guaranted to contain floating point values of
entries of the stack are guaranteed to contain floating point values of
same types.
@item gen_cvt_itof()
@ -1197,10 +1444,6 @@ floating point to integer conversion.
@item gen_cvt_ftof()
floating point to floating point of different size conversion.
@item gen_bounded_ptr_add()
@item gen_bounded_ptr_deref()
are only used for bounds checking.
@end table
@section Optimizations done

11329
tcc.c

File diff suppressed because it is too large Load Diff

2031
tcc.h Normal file

File diff suppressed because it is too large Load Diff

1102
tccasm.c

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,11 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "coff.h"
#include "tcc.h"
/* XXX: this file uses tcc_error() to the effect of exit(1) */
#undef _tcc_error
#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
#define MAX_STR_TABLE 1000000
@ -37,14 +41,14 @@ int EndAddress[MAX_FUNCS];
int LastLineNo[MAX_FUNCS];
int FuncEntries[MAX_FUNCS];
BOOL OutputTheSection(Section * sect);
int OutputTheSection(Section * sect);
short int GetCoffFlags(const char *s);
void SortSymbolTable(void);
void SortSymbolTable(TCCState *s1);
Section *FindSection(TCCState * s1, const char *sname);
int C67_main_entry_point;
int FindCoffSymbolIndex(const char *func_name);
int FindCoffSymbolIndex(TCCState * s1, const char *func_name);
int nb_syms;
typedef struct {
@ -73,7 +77,7 @@ typedef struct {
unsigned short dummy4;
} AUXEF;
int tcc_output_coff(TCCState *s1, FILE *f)
ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
{
Section *tcc_sect;
SCNHDR *coff_sec;
@ -84,12 +88,14 @@ int tcc_output_coff(TCCState *s1, FILE *f)
Section *stext, *sdata, *sbss;
int i, NSectionsToOutput = 0;
Coff_str_table = pCoff_str_table = NULL;
stext = FindSection(s1, ".text");
sdata = FindSection(s1, ".data");
sbss = FindSection(s1, ".bss");
nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1");
coff_nb_syms = FindCoffSymbolIndex(s1, "XXXXXXXXXX1");
file_hdr.f_magic = COFF_C67_MAGIC; /* magic number */
file_hdr.f_timdat = 0; /* time & date stamp */
@ -183,7 +189,7 @@ int tcc_output_coff(TCCState *s1, FILE *f)
coff_sec->s_nlnno = 0;
coff_sec->s_lnnoptr = 0;
if (do_debug && tcc_sect == stext) {
if (s1->do_debug && tcc_sect == stext) {
// count how many line nos data
// also find association between source file name and function
@ -311,7 +317,7 @@ int tcc_output_coff(TCCState *s1, FILE *f)
file_hdr.f_symptr = file_pointer; /* file pointer to symtab */
if (do_debug)
if (s1->do_debug)
file_hdr.f_nsyms = coff_nb_syms; /* number of symtab entries */
else
file_hdr.f_nsyms = 0;
@ -362,8 +368,8 @@ int tcc_output_coff(TCCState *s1, FILE *f)
// group the symbols in order of filename, func1, func2, etc
// finally global symbols
if (do_debug)
SortSymbolTable();
if (s1->do_debug)
SortSymbolTable(s1);
// write line no data
@ -371,7 +377,7 @@ int tcc_output_coff(TCCState *s1, FILE *f)
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (do_debug && tcc_sect == stext) {
if (s1->do_debug && tcc_sect == stext) {
// count how many line nos data
@ -434,7 +440,7 @@ int tcc_output_coff(TCCState *s1, FILE *f)
// output a function begin
CoffLineNo.l_addr.l_symndx =
FindCoffSymbolIndex(func_name);
FindCoffSymbolIndex(s1, func_name);
CoffLineNo.l_lnno = 0;
fwrite(&CoffLineNo, 6, 1, f);
@ -499,7 +505,7 @@ int tcc_output_coff(TCCState *s1, FILE *f)
}
// write symbol table
if (do_debug) {
if (s1->do_debug) {
int k;
struct syment csym;
AUXFUNC auxfunc;
@ -530,7 +536,7 @@ int tcc_output_coff(TCCState *s1, FILE *f)
} else {
if (pCoff_str_table - Coff_str_table + strlen(name) >
MAX_STR_TABLE - 1)
error("String table too large");
tcc_error("String table too large");
csym._n._n_n._n_zeroes = 0;
csym._n._n_n._n_offset =
@ -560,11 +566,7 @@ int tcc_output_coff(TCCState *s1, FILE *f)
}
if (k >= nFuncs) {
char s[256];
sprintf(s, "debug info can't find function: %s", name);
error(s);
tcc_error("debug info can't find function: %s", name);
}
// put a Function Name
@ -670,7 +672,7 @@ int tcc_output_coff(TCCState *s1, FILE *f)
}
}
if (do_debug) {
if (s1->do_debug) {
// write string table
// first write the size
@ -691,7 +693,7 @@ int tcc_output_coff(TCCState *s1, FILE *f)
// group the symbols in order of filename, func1, func2, etc
// finally global symbols
void SortSymbolTable(void)
void SortSymbolTable(TCCState *s1)
{
int i, j, k, n = 0;
Elf32_Sym *p, *p2, *NewTable;
@ -731,13 +733,7 @@ void SortSymbolTable(void)
}
if (k >= nFuncs) {
char s[256];
sprintf(s,
"debug (sort) info can't find function: %s",
name2);
error(s);
tcc_error("debug (sort) info can't find function: %s", name2);
}
if (strcmp(AssociatedFile[k], name) == 0) {
@ -764,7 +760,7 @@ void SortSymbolTable(void)
}
if (n != nb_syms)
error("Internal Compiler error, debug info");
tcc_error("Internal Compiler error, debug info");
// copy it all back
@ -777,7 +773,7 @@ void SortSymbolTable(void)
}
int FindCoffSymbolIndex(const char *func_name)
int FindCoffSymbolIndex(TCCState *s1, const char *func_name)
{
int i, n = 0;
Elf32_Sym *p;
@ -821,14 +817,14 @@ int FindCoffSymbolIndex(const char *func_name)
return n; // total number of symbols
}
BOOL OutputTheSection(Section * sect)
int OutputTheSection(Section * sect)
{
const char *s = sect->name;
if (!strcmp(s, ".text"))
return true;
return 1;
else if (!strcmp(s, ".data"))
return true;
return 1;
else
return 0;
}
@ -861,11 +857,11 @@ Section *FindSection(TCCState * s1, const char *sname)
return s;
}
error("could not find section %s", sname);
tcc_error("could not find section %s", sname);
return 0;
}
int tcc_load_coff(TCCState * s1, int fd)
ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
{
// tktk TokenSym *ts;
@ -879,39 +875,39 @@ int tcc_load_coff(TCCState * s1, int fd)
f = fdopen(fd, "rb");
if (!f) {
error("Unable to open .out file for input");
tcc_error("Unable to open .out file for input");
}
if (fread(&file_hdr, FILHSZ, 1, f) != 1)
error("error reading .out file for input");
tcc_error("error reading .out file for input");
if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1)
error("error reading .out file for input");
tcc_error("error reading .out file for input");
// first read the string table
if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET))
error("error reading .out file for input");
tcc_error("error reading .out file for input");
if (fread(&str_size, sizeof(int), 1, f) != 1)
error("error reading .out file for input");
tcc_error("error reading .out file for input");
Coff_str_table = (char *) tcc_malloc(str_size);
if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
error("error reading .out file for input");
tcc_error("error reading .out file for input");
// read/process all the symbols
// seek back to symbols
if (fseek(f, file_hdr.f_symptr, SEEK_SET))
error("error reading .out file for input");
tcc_error("error reading .out file for input");
for (i = 0; i < file_hdr.f_nsyms; i++) {
if (fread(&csym, SYMESZ, 1, f) != 1)
error("error reading .out file for input");
tcc_error("error reading .out file for input");
if (csym._n._n_n._n_zeroes == 0) {
name = Coff_str_table + csym._n._n_n._n_offset - 4;
@ -940,13 +936,13 @@ int tcc_load_coff(TCCState * s1, int fd)
if (name[0] == '_' && strcmp(name, "_main") != 0)
name++;
tcc_add_symbol(s1, name, csym.n_value);
tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value);
}
// skip any aux records
if (csym.n_numaux == 1) {
if (fread(&csym, SYMESZ, 1, f) != 1)
error("error reading .out file for input");
tcc_error("error reading .out file for input");
i++;
}
}

2676
tccdbg.c Normal file

File diff suppressed because it is too large Load Diff

4968
tccelf.c

File diff suppressed because it is too large Load Diff

8987
tccgen.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,8 @@ void *realloc(void *ptr, size_t size);
int atoi(const char *nptr);
long int strtol(const char *nptr, char **endptr, int base);
unsigned long int strtoul(const char *nptr, char **endptr, int base);
void exit(int);
void *alloca(size_t);
/* stdio.h */
typedef struct __FILE FILE;
@ -38,6 +40,8 @@ int getchar(void);
char *gets(char *s);
int ungetc(int c, FILE *stream);
int fflush(FILE *stream);
int puts(const char *s);
int putchar (int c);
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
@ -63,6 +67,7 @@ void *memcpy(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n);
char *strdup(const char *s);
size_t strlen(const char *s);
/* dlfcn.h */
#define RTLD_LAZY 0x001

2477
tccmacho.c Normal file

File diff suppressed because it is too large Load Diff

2288
tccpe.c

File diff suppressed because it is too large Load Diff

3961
tccpp.c Normal file

File diff suppressed because it is too large Load Diff

1586
tccrun.c Normal file

File diff suppressed because it is too large Load Diff

2005
tcctest.c

File diff suppressed because it is too large Load Diff

610
tcctok.h
View File

@ -1,29 +1,31 @@
/*********************************************************************/
/* keywords */
DEF(TOK_INT, "int")
DEF(TOK_VOID, "void")
DEF(TOK_CHAR, "char")
DEF(TOK_IF, "if")
DEF(TOK_ELSE, "else")
DEF(TOK_WHILE, "while")
DEF(TOK_FOR, "for")
DEF(TOK_DO, "do")
DEF(TOK_CONTINUE, "continue")
DEF(TOK_BREAK, "break")
DEF(TOK_RETURN, "return")
DEF(TOK_FOR, "for")
DEF(TOK_GOTO, "goto")
DEF(TOK_SWITCH, "switch")
DEF(TOK_CASE, "case")
DEF(TOK_DEFAULT, "default")
DEF(TOK_ASM1, "asm")
DEF(TOK_ASM2, "__asm")
DEF(TOK_ASM3, "__asm__")
DEF(TOK_EXTERN, "extern")
DEF(TOK_STATIC, "static")
DEF(TOK_UNSIGNED, "unsigned")
DEF(TOK_GOTO, "goto")
DEF(TOK_DO, "do")
DEF(TOK_CONTINUE, "continue")
DEF(TOK_SWITCH, "switch")
DEF(TOK_CASE, "case")
DEF(TOK__Atomic, "_Atomic")
DEF(TOK_CONST1, "const")
DEF(TOK_CONST2, "__const") /* gcc keyword */
DEF(TOK_CONST3, "__const__") /* gcc keyword */
DEF(TOK_VOLATILE1, "volatile")
DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */
DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */
DEF(TOK_LONG, "long")
DEF(TOK_REGISTER, "register")
DEF(TOK_SIGNED1, "signed")
DEF(TOK_SIGNED2, "__signed") /* gcc keyword */
@ -36,28 +38,36 @@
DEF(TOK_RESTRICT2, "__restrict")
DEF(TOK_RESTRICT3, "__restrict__")
DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
DEF(TOK_THREAD_LOCAL, "_Thread_local") /* C11 thread-local storage */
DEF(TOK___thread, "__thread") /* GCC thread-local storage extension */
DEF(TOK_GENERIC, "_Generic")
DEF(TOK_STATIC_ASSERT, "_Static_assert")
DEF(TOK_VOID, "void")
DEF(TOK_CHAR, "char")
DEF(TOK_INT, "int")
DEF(TOK_FLOAT, "float")
DEF(TOK_DOUBLE, "double")
DEF(TOK_BOOL, "_Bool")
DEF(TOK_COMPLEX, "_Complex")
DEF(TOK_SHORT, "short")
DEF(TOK_LONG, "long")
DEF(TOK_STRUCT, "struct")
DEF(TOK_UNION, "union")
DEF(TOK_TYPEDEF, "typedef")
DEF(TOK_DEFAULT, "default")
DEF(TOK_ENUM, "enum")
DEF(TOK_SIZEOF, "sizeof")
DEF(TOK_ATTRIBUTE1, "__attribute")
DEF(TOK_ATTRIBUTE2, "__attribute__")
DEF(TOK_ALIGNOF1, "__alignof")
DEF(TOK_ALIGNOF2, "__alignof__")
DEF(TOK_ALIGNOF3, "_Alignof")
DEF(TOK_ALIGNAS, "_Alignas")
DEF(TOK_TYPEOF1, "typeof")
DEF(TOK_TYPEOF2, "__typeof")
DEF(TOK_TYPEOF3, "__typeof__")
DEF(TOK_LABEL, "__label__")
DEF(TOK_ASM1, "asm")
DEF(TOK_ASM2, "__asm")
DEF(TOK_ASM3, "__asm__")
/*********************************************************************/
/* the following are not keywords. They are included to ease parsing */
@ -81,10 +91,18 @@
DEF(TOK___TIME__, "__TIME__")
DEF(TOK___FUNCTION__, "__FUNCTION__")
DEF(TOK___VA_ARGS__, "__VA_ARGS__")
DEF(TOK___COUNTER__, "__COUNTER__")
DEF(TOK___HAS_INCLUDE, "__has_include")
DEF(TOK___HAS_INCLUDE_NEXT, "__has_include_next")
/* special identifiers */
DEF(TOK___FUNC__, "__func__")
/* special floating point values */
DEF(TOK___NAN__, "__nan__")
DEF(TOK___SNAN__, "__snan__")
DEF(TOK___INF__, "__inf__")
/* attribute identifiers */
/* XXX: handle all tokens generically since speed is not critical */
DEF(TOK_SECTION1, "section")
@ -93,8 +111,18 @@
DEF(TOK_ALIGNED2, "__aligned__")
DEF(TOK_PACKED1, "packed")
DEF(TOK_PACKED2, "__packed__")
DEF(TOK_WEAK1, "weak")
DEF(TOK_WEAK2, "__weak__")
DEF(TOK_ALIAS1, "alias")
DEF(TOK_ALIAS2, "__alias__")
DEF(TOK_USED1, "used")
DEF(TOK_USED2, "__used__")
DEF(TOK_UNUSED1, "unused")
DEF(TOK_UNUSED2, "__unused__")
DEF(TOK_FORMAT1, "format")
DEF(TOK_FORMAT2, "__format__")
DEF(TOK_NODEBUG1, "nodebug")
DEF(TOK_NODEBUG2, "__nodebug__")
DEF(TOK_CDECL1, "cdecl")
DEF(TOK_CDECL2, "__cdecl")
DEF(TOK_CDECL3, "__cdecl__")
@ -104,98 +132,212 @@
DEF(TOK_FASTCALL1, "fastcall")
DEF(TOK_FASTCALL2, "__fastcall")
DEF(TOK_FASTCALL3, "__fastcall__")
DEF(TOK_DLLEXPORT, "dllexport")
DEF(TOK_NORETURN1, "noreturn")
DEF(TOK_NORETURN2, "__noreturn__")
DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
DEF(TOK_builtin_constant_p, "__builtin_constant_p")
DEF(TOK_THISCALL1, "thiscall")
DEF(TOK_THISCALL2, "__thiscall")
DEF(TOK_THISCALL3, "__thiscall__")
DEF(TOK_REGPARM1, "regparm")
DEF(TOK_REGPARM2, "__regparm__")
DEF(TOK_CLEANUP1, "cleanup")
DEF(TOK_CLEANUP2, "__cleanup__")
DEF(TOK_CONSTRUCTOR1, "constructor")
DEF(TOK_CONSTRUCTOR2, "__constructor__")
DEF(TOK_DESTRUCTOR1, "destructor")
DEF(TOK_DESTRUCTOR2, "__destructor__")
DEF(TOK_ALWAYS_INLINE1, "always_inline")
DEF(TOK_ALWAYS_INLINE2, "__always_inline__")
DEF(TOK_NOINLINE, "__noinline__")
DEF(TOK_PURE1, "pure")
DEF(TOK_PURE2, "__pure__")
DEF(TOK_MODE, "__mode__")
DEF(TOK_MODE_QI, "__QI__")
DEF(TOK_MODE_DI, "__DI__")
DEF(TOK_MODE_HI, "__HI__")
DEF(TOK_MODE_SI, "__SI__")
DEF(TOK_MODE_word, "__word__")
DEF(TOK_DLLEXPORT, "dllexport")
DEF(TOK_DLLIMPORT, "dllimport")
DEF(TOK_NODECORATE, "nodecorate")
DEF(TOK_NORETURN1, "noreturn")
DEF(TOK_NORETURN2, "__noreturn__")
DEF(TOK_NORETURN3, "_Noreturn")
DEF(TOK_VISIBILITY1, "visibility")
DEF(TOK_VISIBILITY2, "__visibility__")
DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
DEF(TOK_builtin_choose_expr, "__builtin_choose_expr")
DEF(TOK_builtin_constant_p, "__builtin_constant_p")
DEF(TOK_builtin_frame_address, "__builtin_frame_address")
DEF(TOK_builtin_return_address, "__builtin_return_address")
DEF(TOK_builtin_expect, "__builtin_expect")
DEF(TOK_builtin_unreachable, "__builtin_unreachable")
/*DEF(TOK_builtin_va_list, "__builtin_va_list")*/
#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
DEF(TOK_builtin_va_start, "__builtin_va_start")
#elif defined TCC_TARGET_X86_64
DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types")
#elif defined TCC_TARGET_ARM64
DEF(TOK_builtin_va_start, "__builtin_va_start")
DEF(TOK_builtin_va_arg, "__builtin_va_arg")
#elif defined TCC_TARGET_RISCV64
DEF(TOK_builtin_va_start, "__builtin_va_start")
#endif
/* atomic operations */
#define DEF_ATOMIC(ID) DEF(TOK_##__##ID, "__"#ID)
DEF_ATOMIC(atomic_store)
DEF_ATOMIC(atomic_load)
DEF_ATOMIC(atomic_exchange)
DEF_ATOMIC(atomic_compare_exchange)
DEF_ATOMIC(atomic_fetch_add)
DEF_ATOMIC(atomic_fetch_sub)
DEF_ATOMIC(atomic_fetch_or)
DEF_ATOMIC(atomic_fetch_xor)
DEF_ATOMIC(atomic_fetch_and)
DEF_ATOMIC(atomic_fetch_nand)
DEF_ATOMIC(atomic_add_fetch)
DEF_ATOMIC(atomic_sub_fetch)
DEF_ATOMIC(atomic_or_fetch)
DEF_ATOMIC(atomic_xor_fetch)
DEF_ATOMIC(atomic_and_fetch)
DEF_ATOMIC(atomic_nand_fetch)
/* pragma */
DEF(TOK_pack, "pack")
#if !defined(TCC_TARGET_I386)
#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64) && \
!defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_ARM64) && \
!defined(TCC_TARGET_RISCV64)
/* already defined for assembler */
DEF(TOK_ASM_push, "push")
DEF(TOK_ASM_pop, "pop")
#endif
DEF(TOK_comment, "comment")
DEF(TOK_lib, "lib")
DEF(TOK_push_macro, "push_macro")
DEF(TOK_pop_macro, "pop_macro")
DEF(TOK_once, "once")
DEF(TOK_option, "option")
/* builtin functions or variables */
#ifdef TCC_ARM_EABI
DEF(TOK_memcpy, "__aeabi_memcpy")
DEF(TOK_memcpy4, "__aeabi_memcpy4")
DEF(TOK_memcpy8, "__aeabi_memcpy8")
DEF(TOK_memset, "__aeabi_memset")
#else
#ifndef TCC_ARM_EABI
DEF(TOK_memcpy, "memcpy")
DEF(TOK_memmove, "memmove")
DEF(TOK_memset, "memset")
#endif
DEF(TOK___divdi3, "__divdi3")
DEF(TOK___moddi3, "__moddi3")
DEF(TOK___udivdi3, "__udivdi3")
DEF(TOK___umoddi3, "__umoddi3")
#if defined(TCC_TARGET_ARM)
DEF(TOK___modsi3, "__modsi3")
DEF(TOK___umodsi3, "__umodsi3")
#ifdef TCC_ARM_EABI
DEF(TOK___ashrdi3, "__ashrdi3")
DEF(TOK___lshrdi3, "__lshrdi3")
DEF(TOK___ashldi3, "__ashldi3")
DEF(TOK___floatundisf, "__floatundisf")
DEF(TOK___floatundidf, "__floatundidf")
# ifndef TCC_ARM_VFP
DEF(TOK___floatundixf, "__floatundixf")
DEF(TOK___fixunsxfdi, "__fixunsxfdi")
# endif
DEF(TOK___fixunssfdi, "__fixunssfdi")
DEF(TOK___fixunsdfdi, "__fixunsdfdi")
#endif
#if defined TCC_TARGET_ARM
# ifdef TCC_ARM_EABI
DEF(TOK_memcpy, "__aeabi_memcpy")
DEF(TOK_memmove, "__aeabi_memmove")
DEF(TOK_memmove4, "__aeabi_memmove4")
DEF(TOK_memmove8, "__aeabi_memmove8")
DEF(TOK_memset, "__aeabi_memset")
DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod")
DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod")
DEF(TOK___aeabi_idivmod, "__aeabi_idivmod")
DEF(TOK___aeabi_uidivmod, "__aeabi_uidivmod")
DEF(TOK___divsi3, "__aeabi_idiv")
DEF(TOK___udivsi3, "__aeabi_uidiv")
DEF(TOK___sardi3, "__aeabi_lasr")
DEF(TOK___shrdi3, "__aeabi_llsr")
DEF(TOK___shldi3, "__aeabi_llsl")
DEF(TOK___slltof, "__aeabi_l2f")
DEF(TOK___slltold, "__aeabi_l2d")
DEF(TOK___floatdisf, "__aeabi_l2f")
DEF(TOK___floatdidf, "__aeabi_l2d")
DEF(TOK___fixsfdi, "__aeabi_f2lz")
DEF(TOK___fixdfdi, "__aeabi_d2lz")
DEF(TOK___fixxfdi, "__aeabi_d2lz")
#else
DEF(TOK___ashrdi3, "__aeabi_lasr")
DEF(TOK___lshrdi3, "__aeabi_llsr")
DEF(TOK___ashldi3, "__aeabi_llsl")
DEF(TOK___floatundisf, "__aeabi_ul2f")
DEF(TOK___floatundidf, "__aeabi_ul2d")
DEF(TOK___fixunssfdi, "__aeabi_f2ulz")
DEF(TOK___fixunsdfdi, "__aeabi_d2ulz")
# else
DEF(TOK___modsi3, "__modsi3")
DEF(TOK___umodsi3, "__umodsi3")
DEF(TOK___divsi3, "__divsi3")
DEF(TOK___udivsi3, "__udivsi3")
DEF(TOK___sardi3, "__ashrdi3")
DEF(TOK___shrdi3, "__lshrdi3")
DEF(TOK___shldi3, "__ashldi3")
DEF(TOK___slltold, "__slltold")
DEF(TOK___floatdisf, "__floatdisf")
DEF(TOK___floatdidf, "__floatdidf")
# ifndef TCC_ARM_VFP
DEF(TOK___floatdixf, "__floatdixf")
DEF(TOK___fixunssfsi, "__fixunssfsi")
DEF(TOK___fixunsdfsi, "__fixunsdfsi")
DEF(TOK___fixunsxfsi, "__fixunsxfsi")
DEF(TOK___fixxfdi, "__fixxfdi")
# endif
DEF(TOK___fixsfdi, "__fixsfdi")
DEF(TOK___fixdfdi, "__fixdfdi")
DEF(TOK___fixxfdi, "__fixxfdi")
# endif
#endif
#elif defined(TCC_TARGET_C67)
#if defined TCC_TARGET_C67
DEF(TOK__divi, "_divi")
DEF(TOK__divu, "_divu")
DEF(TOK__divf, "_divf")
DEF(TOK__divd, "_divd")
DEF(TOK__remi, "_remi")
DEF(TOK__remu, "_remu")
DEF(TOK___sardi3, "__sardi3")
DEF(TOK___shrdi3, "__shrdi3")
DEF(TOK___shldi3, "__shldi3")
#else
/* XXX: same names on i386 ? */
DEF(TOK___sardi3, "__sardi3")
DEF(TOK___shrdi3, "__shrdi3")
DEF(TOK___shldi3, "__shldi3")
#endif
DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control")
DEF(TOK___tcc_fpu_control, "__tcc_fpu_control")
#ifdef TCC_ARM_EABI
DEF(TOK___ulltof, "__aeabi_ul2f")
DEF(TOK___ulltod, "__aeabi_ul2d")
DEF(TOK___ulltold, "__aeabi_ul2d")
DEF(TOK___fixunssfdi, "__aeabi_f2ulz")
DEF(TOK___fixunsdfdi, "__aeabi_d2ulz")
DEF(TOK___fixunsxfdi, "__aeabi_d2ulz")
#else
DEF(TOK___ulltof, "__ulltof")
DEF(TOK___ulltod, "__ulltod")
DEF(TOK___ulltold, "__ulltold")
DEF(TOK___fixunssfdi, "__fixunssfdi")
DEF(TOK___fixunsdfdi, "__fixunsdfdi")
DEF(TOK___fixunsxfdi, "__fixunsxfdi")
#if defined TCC_TARGET_I386
DEF(TOK___fixsfdi, "__fixsfdi")
DEF(TOK___fixdfdi, "__fixdfdi")
DEF(TOK___fixxfdi, "__fixxfdi")
#endif
#if defined TCC_TARGET_X86_64
DEF(TOK___fixxfdi, "__fixxfdi")
#endif
DEF(TOK_alloca, "alloca")
#if defined TCC_TARGET_PE
DEF(TOK___chkstk, "__chkstk")
#endif
#ifdef TCC_TARGET_ARM64
DEF(TOK___arm64_clear_cache, "__arm64_clear_cache")
#endif
#ifdef TCC_TARGET_RISCV64
DEF(TOK___riscv64_clear_cache, "__riscv64_clear_cache")
#endif
#if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
DEF(TOK___addtf3, "__addtf3")
DEF(TOK___subtf3, "__subtf3")
DEF(TOK___multf3, "__multf3")
DEF(TOK___divtf3, "__divtf3")
DEF(TOK___extendsftf2, "__extendsftf2")
DEF(TOK___extenddftf2, "__extenddftf2")
DEF(TOK___trunctfsf2, "__trunctfsf2")
DEF(TOK___trunctfdf2, "__trunctfdf2")
DEF(TOK___negtf2, "__negtf2")
DEF(TOK___fixtfsi, "__fixtfsi")
DEF(TOK___fixtfdi, "__fixtfdi")
DEF(TOK___fixunstfsi, "__fixunstfsi")
DEF(TOK___fixunstfdi, "__fixunstfdi")
DEF(TOK___floatsitf, "__floatsitf")
DEF(TOK___floatditf, "__floatditf")
DEF(TOK___floatunsitf, "__floatunsitf")
DEF(TOK___floatunditf, "__floatunditf")
DEF(TOK___eqtf2, "__eqtf2")
DEF(TOK___netf2, "__netf2")
DEF(TOK___lttf2, "__lttf2")
DEF(TOK___letf2, "__letf2")
DEF(TOK___gttf2, "__gttf2")
DEF(TOK___getf2, "__getf2")
#endif
/* bound checking symbols */
#ifdef CONFIG_TCC_BCHECK
@ -206,252 +348,94 @@
DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
DEF(TOK___bound_main_arg, "__bound_main_arg")
DEF(TOK___bound_local_new, "__bound_local_new")
DEF(TOK___bound_local_delete, "__bound_local_delete")
DEF(TOK_malloc, "malloc")
DEF(TOK_free, "free")
DEF(TOK_realloc, "realloc")
DEF(TOK_memalign, "memalign")
DEF(TOK_calloc, "calloc")
DEF(TOK_memmove, "memmove")
DEF(TOK_strlen, "strlen")
DEF(TOK_strcpy, "strcpy")
DEF(TOK__alloca, "_alloca")
DEF(TOK___bound_setjmp, "__bound_setjmp")
DEF(TOK___bound_longjmp, "__bound_longjmp")
DEF(TOK___bound_new_region, "__bound_new_region")
# ifdef TCC_TARGET_PE
# ifdef TCC_TARGET_X86_64
DEF(TOK___bound_alloca_nr, "__bound_alloca_nr")
# endif
# else
DEF(TOK_sigsetjmp, "sigsetjmp")
DEF(TOK___sigsetjmp, "__sigsetjmp")
DEF(TOK_siglongjmp, "siglongjmp")
# endif
DEF(TOK_setjmp, "setjmp")
DEF(TOK__setjmp, "_setjmp")
DEF(TOK_longjmp, "longjmp")
#endif
/*********************************************************************/
/* Tiny Assembler */
#define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
#define DEF_ASMDIR(x) DEF(TOK_ASMDIR_ ## x, "." #x)
#define TOK_ASM_int TOK_INT
DEF_ASM(byte)
DEF_ASM(align)
DEF_ASM(skip)
DEF_ASM(space)
DEF_ASM(string)
DEF_ASM(asciz)
DEF_ASM(ascii)
DEF_ASM(globl)
DEF_ASM(global)
DEF_ASM(text)
DEF_ASM(data)
DEF_ASM(bss)
DEF_ASM(previous)
DEF_ASM(fill)
DEF_ASM(org)
DEF_ASM(quad)
#ifdef TCC_TARGET_I386
/* WARNING: relative order of tokens is important. */
DEF_ASM(al)
DEF_ASM(cl)
DEF_ASM(dl)
DEF_ASM(bl)
DEF_ASM(ah)
DEF_ASM(ch)
DEF_ASM(dh)
DEF_ASM(bh)
DEF_ASM(ax)
DEF_ASM(cx)
DEF_ASM(dx)
DEF_ASM(bx)
DEF_ASM(sp)
DEF_ASM(bp)
DEF_ASM(si)
DEF_ASM(di)
DEF_ASM(eax)
DEF_ASM(ecx)
DEF_ASM(edx)
DEF_ASM(ebx)
DEF_ASM(esp)
DEF_ASM(ebp)
DEF_ASM(esi)
DEF_ASM(edi)
DEF_ASM(mm0)
DEF_ASM(mm1)
DEF_ASM(mm2)
DEF_ASM(mm3)
DEF_ASM(mm4)
DEF_ASM(mm5)
DEF_ASM(mm6)
DEF_ASM(mm7)
DEF_ASM(xmm0)
DEF_ASM(xmm1)
DEF_ASM(xmm2)
DEF_ASM(xmm3)
DEF_ASM(xmm4)
DEF_ASM(xmm5)
DEF_ASM(xmm6)
DEF_ASM(xmm7)
DEF_ASM(cr0)
DEF_ASM(cr1)
DEF_ASM(cr2)
DEF_ASM(cr3)
DEF_ASM(cr4)
DEF_ASM(cr5)
DEF_ASM(cr6)
DEF_ASM(cr7)
DEF_ASM(tr0)
DEF_ASM(tr1)
DEF_ASM(tr2)
DEF_ASM(tr3)
DEF_ASM(tr4)
DEF_ASM(tr5)
DEF_ASM(tr6)
DEF_ASM(tr7)
DEF_ASM(db0)
DEF_ASM(db1)
DEF_ASM(db2)
DEF_ASM(db3)
DEF_ASM(db4)
DEF_ASM(db5)
DEF_ASM(db6)
DEF_ASM(db7)
DEF_ASM(dr0)
DEF_ASM(dr1)
DEF_ASM(dr2)
DEF_ASM(dr3)
DEF_ASM(dr4)
DEF_ASM(dr5)
DEF_ASM(dr6)
DEF_ASM(dr7)
DEF_ASM(es)
DEF_ASM(cs)
DEF_ASM(ss)
DEF_ASM(ds)
DEF_ASM(fs)
DEF_ASM(gs)
DEF_ASM(st)
DEF_BWL(mov)
/* generic two operands */
DEF_BWL(add)
DEF_BWL(or)
DEF_BWL(adc)
DEF_BWL(sbb)
DEF_BWL(and)
DEF_BWL(sub)
DEF_BWL(xor)
DEF_BWL(cmp)
/* unary ops */
DEF_BWL(inc)
DEF_BWL(dec)
DEF_BWL(not)
DEF_BWL(neg)
DEF_BWL(mul)
DEF_BWL(imul)
DEF_BWL(div)
DEF_BWL(idiv)
DEF_BWL(xchg)
DEF_BWL(test)
/* shifts */
DEF_BWL(rol)
DEF_BWL(ror)
DEF_BWL(rcl)
DEF_BWL(rcr)
DEF_BWL(shl)
DEF_BWL(shr)
DEF_BWL(sar)
DEF_ASM(shldw)
DEF_ASM(shldl)
DEF_ASM(shld)
DEF_ASM(shrdw)
DEF_ASM(shrdl)
DEF_ASM(shrd)
DEF_ASM(pushw)
DEF_ASM(pushl)
DEF_ASM(push)
DEF_ASM(popw)
DEF_ASM(popl)
DEF_ASM(pop)
DEF_BWL(in)
DEF_BWL(out)
DEF_WL(movzb)
DEF_ASM(movzwl)
DEF_ASM(movsbw)
DEF_ASM(movsbl)
DEF_ASM(movswl)
DEF_WL(lea)
DEF_ASM(les)
DEF_ASM(lds)
DEF_ASM(lss)
DEF_ASM(lfs)
DEF_ASM(lgs)
DEF_ASM(call)
DEF_ASM(jmp)
DEF_ASM(lcall)
DEF_ASM(ljmp)
DEF_ASMTEST(j)
DEF_ASMTEST(set)
DEF_ASMTEST(cmov)
DEF_WL(bsf)
DEF_WL(bsr)
DEF_WL(bt)
DEF_WL(bts)
DEF_WL(btr)
DEF_WL(btc)
DEF_WL(lsl)
/* generic FP ops */
DEF_FP(add)
DEF_FP(mul)
DEF_ASM(fcom)
DEF_ASM(fcom_1) /* non existant op, just to have a regular table */
DEF_FP1(com)
DEF_FP(comp)
DEF_FP(sub)
DEF_FP(subr)
DEF_FP(div)
DEF_FP(divr)
DEF_BWL(xadd)
DEF_BWL(cmpxchg)
/* string ops */
DEF_BWL(cmps)
DEF_BWL(scmp)
DEF_BWL(ins)
DEF_BWL(outs)
DEF_BWL(lods)
DEF_BWL(slod)
DEF_BWL(movs)
DEF_BWL(smov)
DEF_BWL(scas)
DEF_BWL(ssca)
DEF_BWL(stos)
DEF_BWL(ssto)
/* generic asm ops */
#define ALT(x)
#define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
#define DEF_ASM_OP0L(name, opcode, group, instr_type)
#define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
#include "i386-asm.h"
#define ALT(x)
#define DEF_ASM_OP0(name, opcode)
#define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
#include "i386-asm.h"
#define TOK_ASMDIR_FIRST TOK_ASMDIR_byte
#define TOK_ASMDIR_LAST TOK_ASMDIR_section
DEF_ASMDIR(byte) /* must be first directive */
DEF_ASMDIR(word)
DEF_ASMDIR(align)
DEF_ASMDIR(balign)
DEF_ASMDIR(p2align)
DEF_ASMDIR(set)
DEF_ASMDIR(skip)
DEF_ASMDIR(space)
DEF_ASMDIR(string)
DEF_ASMDIR(asciz)
DEF_ASMDIR(ascii)
DEF_ASMDIR(file)
DEF_ASMDIR(globl)
DEF_ASMDIR(global)
DEF_ASMDIR(weak)
DEF_ASMDIR(hidden)
DEF_ASMDIR(ident)
DEF_ASMDIR(size)
DEF_ASMDIR(type)
DEF_ASMDIR(text)
DEF_ASMDIR(data)
DEF_ASMDIR(bss)
DEF_ASMDIR(previous)
DEF_ASMDIR(pushsection)
DEF_ASMDIR(popsection)
DEF_ASMDIR(fill)
DEF_ASMDIR(rept)
DEF_ASMDIR(endr)
DEF_ASMDIR(org)
DEF_ASMDIR(quad)
#if PTR_SIZE == 4
DEF_ASMDIR(code16)
DEF_ASMDIR(code32)
#else
DEF_ASMDIR(code64)
#endif
#if defined(TCC_TARGET_RISCV64)
DEF_ASMDIR(option)
#endif
DEF_ASMDIR(short)
DEF_ASMDIR(long)
DEF_ASMDIR(int)
DEF_ASMDIR(symver)
DEF_ASMDIR(reloc)
DEF_ASMDIR(section) /* must be last directive */
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
#include "i386-tok.h"
#endif
#if defined TCC_TARGET_ARM
#include "arm-tok.h"
#endif
#if defined TCC_TARGET_ARM64
#include "arm64-tok.h"
#endif
#if defined TCC_TARGET_RISCV64
#include "riscv64-tok.h"
#endif

651
tcctools.c Normal file
View File

@ -0,0 +1,651 @@
/* -------------------------------------------------------------- */
/*
* TCC - Tiny C Compiler
*
* tcctools.c - extra tools and and -m32/64 support
*
*/
/* -------------------------------------------------------------- */
/*
* This program is for making libtcc1.a without ar
* tiny_libmaker - tiny elf lib maker
* usage: tiny_libmaker [lib] files...
* Copyright (c) 2007 Timppa
*
* This 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 of the License, or (at your option) any later version.
*
* This 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "tcc.h"
//#define ARMAG "!<arch>\n"
#define ARFMAG "`\n"
typedef struct {
char ar_name[16];
char ar_date[12];
char ar_uid[6];
char ar_gid[6];
char ar_mode[8];
char ar_size[10];
char ar_fmag[2];
} ArHdr;
static unsigned long le2belong(unsigned long ul) {
return ((ul & 0xFF0000)>>8)+((ul & 0xFF000000)>>24) +
((ul & 0xFF)<<24)+((ul & 0xFF00)<<8);
}
static int ar_usage(int ret) {
fprintf(stderr, "usage: tcc -ar [crstvx] lib [files]\n");
fprintf(stderr, "create library ([abdiopN] not supported).\n");
return ret;
}
ST_FUNC int tcc_tool_ar(int argc, char **argv)
{
static const ArHdr arhdr_init = {
"/ ",
"0 ",
"0 ",
"0 ",
"0 ",
"0 ",
ARFMAG
};
ArHdr arhdr = arhdr_init;
ArHdr arhdro = arhdr_init;
FILE *fi, *fh = NULL, *fo = NULL;
const char *created_file = NULL; // must delete on error
ElfW(Ehdr) *ehdr;
ElfW(Shdr) *shdr;
ElfW(Sym) *sym;
int i, fsize, i_lib, i_obj;
char *buf, *shstr, *symtab, *strtab;
int symtabsize = 0;//, strtabsize = 0;
char *anames = NULL;
int *afpos = NULL;
int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs;
char tfile[260], stmp[20];
char *file, *name;
int ret = 2;
const char *ops_conflict = "habdiopN"; // unsupported but destructive if ignored.
int extract = 0;
int table = 0;
int verbose = 0;
i_lib = 0; i_obj = 0; // will hold the index of the lib and first obj
for (i = 1; i < argc; i++) {
const char *a = argv[i];
if (*a == '-' && strchr(a, '.'))
ret = 1; // -x.y is always invalid (same as gnu ar)
if ((*a == '-') || (i == 1 && !strchr(a, '.'))) { // options argument
if (strpbrk(a, ops_conflict))
ret = 1;
if (strchr(a, 'x'))
extract = 1;
if (strchr(a, 't'))
table = 1;
if (strchr(a, 'v'))
verbose = 1;
} else { // lib or obj files: don't abort - keep validating all args.
if (!i_lib) // first file is the lib
i_lib = i;
else if (!i_obj) // second file is the first obj
i_obj = i;
}
}
if (!i_lib) // i_obj implies also i_lib.
ret = 1;
i_obj = i_obj ? i_obj : argc; // An empty archive will be generated if no input file is given
if (ret == 1)
return ar_usage(ret);
if (extract || table) {
if ((fh = fopen(argv[i_lib], "rb")) == NULL)
{
fprintf(stderr, "tcc: ar: can't open file %s\n", argv[i_lib]);
goto finish;
}
fread(stmp, 1, 8, fh);
if (memcmp(stmp,ARMAG,8))
{
no_ar:
fprintf(stderr, "tcc: ar: not an ar archive %s\n", argv[i_lib]);
goto finish;
}
while (fread(&arhdr, 1, sizeof(arhdr), fh) == sizeof(arhdr)) {
char *p, *e;
if (memcmp(arhdr.ar_fmag, ARFMAG, 2))
goto no_ar;
p = arhdr.ar_name;
for (e = p + sizeof arhdr.ar_name; e > p && e[-1] == ' ';)
e--;
*e = '\0';
arhdr.ar_size[sizeof arhdr.ar_size-1] = 0;
fsize = atoi(arhdr.ar_size);
buf = tcc_malloc(fsize + 1);
fread(buf, fsize, 1, fh);
if (strcmp(arhdr.ar_name,"/") && strcmp(arhdr.ar_name,"/SYM64/")) {
if (e > p && e[-1] == '/')
e[-1] = '\0';
/* tv not implemented */
if (table || verbose)
printf("%s%s\n", extract ? "x - " : "", arhdr.ar_name);
if (extract) {
if ((fo = fopen(arhdr.ar_name, "wb")) == NULL)
{
fprintf(stderr, "tcc: ar: can't create file %s\n",
arhdr.ar_name);
tcc_free(buf);
goto finish;
}
fwrite(buf, fsize, 1, fo);
fclose(fo);
/* ignore date/uid/gid/mode */
}
}
if (fsize & 1)
fgetc(fh);
tcc_free(buf);
}
ret = 0;
finish:
if (fh)
fclose(fh);
return ret;
}
if ((fh = fopen(argv[i_lib], "wb")) == NULL)
{
fprintf(stderr, "tcc: ar: can't create file %s\n", argv[i_lib]);
goto the_end;
}
created_file = argv[i_lib];
sprintf(tfile, "%s.tmp", argv[i_lib]);
if ((fo = fopen(tfile, "wb+")) == NULL)
{
fprintf(stderr, "tcc: ar: can't create temporary file %s\n", tfile);
goto the_end;
}
funcmax = 250;
afpos = tcc_realloc(NULL, funcmax * sizeof *afpos); // 250 func
memcpy(&arhdro.ar_mode, "100644", 6);
// i_obj = first input object file
while (i_obj < argc)
{
if (*argv[i_obj] == '-') { // by now, all options start with '-'
i_obj++;
continue;
}
if ((fi = fopen(argv[i_obj], "rb")) == NULL) {
fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_obj]);
goto the_end;
}
if (verbose)
printf("a - %s\n", argv[i_obj]);
fseek(fi, 0, SEEK_END);
fsize = ftell(fi);
fseek(fi, 0, SEEK_SET);
buf = tcc_malloc(fsize + 1);
fread(buf, fsize, 1, fi);
fclose(fi);
// elf header
ehdr = (ElfW(Ehdr) *)buf;
if (ehdr->e_ident[4] != ELFCLASSW)
{
fprintf(stderr, "tcc: ar: Unsupported Elf Class: %s\n", argv[i_obj]);
goto the_end;
}
shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize);
shstr = (char *)(buf + shdr->sh_offset);
symtab = strtab = NULL;
for (i = 0; i < ehdr->e_shnum; i++)
{
shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + i * ehdr->e_shentsize);
if (!shdr->sh_offset)
continue;
if (shdr->sh_type == SHT_SYMTAB)
{
symtab = (char *)(buf + shdr->sh_offset);
symtabsize = shdr->sh_size;
}
if (shdr->sh_type == SHT_STRTAB)
{
if (!strcmp(shstr + shdr->sh_name, ".strtab"))
{
strtab = (char *)(buf + shdr->sh_offset);
//strtabsize = shdr->sh_size;
}
}
}
if (symtab && strtab)
{
int nsym = symtabsize / sizeof(ElfW(Sym));
//printf("symtab: info size shndx name\n");
for (i = 1; i < nsym; i++)
{
sym = (ElfW(Sym) *) (symtab + i * sizeof(ElfW(Sym)));
if (sym->st_shndx &&
(sym->st_info == 0x10
|| sym->st_info == 0x11
|| sym->st_info == 0x12
|| sym->st_info == 0x20
|| sym->st_info == 0x21
|| sym->st_info == 0x22
)) {
//printf("symtab: %2Xh %4Xh %2Xh %s\n", sym->st_info, sym->st_size, sym->st_shndx, strtab + sym->st_name);
istrlen = strlen(strtab + sym->st_name)+1;
anames = tcc_realloc(anames, strpos+istrlen);
strcpy(anames + strpos, strtab + sym->st_name);
strpos += istrlen;
if (++funccnt >= funcmax) {
funcmax += 250;
afpos = tcc_realloc(afpos, funcmax * sizeof *afpos); // 250 func more
}
afpos[funccnt] = fpos;
}
}
}
file = argv[i_obj];
for (name = strchr(file, 0);
name > file && name[-1] != '/' && name[-1] != '\\';
--name);
istrlen = strlen(name);
if (istrlen >= sizeof(arhdro.ar_name))
istrlen = sizeof(arhdro.ar_name) - 1;
memset(arhdro.ar_name, ' ', sizeof(arhdro.ar_name));
memcpy(arhdro.ar_name, name, istrlen);
arhdro.ar_name[istrlen] = '/';
sprintf(stmp, "%-10d", fsize);
memcpy(&arhdro.ar_size, stmp, 10);
fwrite(&arhdro, sizeof(arhdro), 1, fo);
fwrite(buf, fsize, 1, fo);
tcc_free(buf);
i_obj++;
fpos += (fsize + sizeof(arhdro));
if (fpos & 1)
fputc(0, fo), ++fpos;
}
hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int);
fpos = 0;
if ((hofs & 1)) // align
hofs++, fpos = 1;
// write header
fwrite(ARMAG, 8, 1, fh);
// create an empty archive
if (!funccnt) {
ret = 0;
goto the_end;
}
sprintf(stmp, "%-10d", (int)(strpos + (funccnt+1) * sizeof(int)) + fpos);
memcpy(&arhdr.ar_size, stmp, 10);
fwrite(&arhdr, sizeof(arhdr), 1, fh);
afpos[0] = le2belong(funccnt);
for (i=1; i<=funccnt; i++)
afpos[i] = le2belong(afpos[i] + hofs);
fwrite(afpos, (funccnt+1) * sizeof(int), 1, fh);
fwrite(anames, strpos, 1, fh);
if (fpos)
fwrite("", 1, 1, fh);
// write objects
fseek(fo, 0, SEEK_END);
fsize = ftell(fo);
fseek(fo, 0, SEEK_SET);
buf = tcc_malloc(fsize + 1);
fread(buf, fsize, 1, fo);
fwrite(buf, fsize, 1, fh);
tcc_free(buf);
ret = 0;
the_end:
if (anames)
tcc_free(anames);
if (afpos)
tcc_free(afpos);
if (fh)
fclose(fh);
if (created_file && ret != 0)
remove(created_file);
if (fo)
fclose(fo), remove(tfile);
return ret;
}
/* -------------------------------------------------------------- */
/*
* tiny_impdef creates an export definition file (.def) from a dll
* on MS-Windows. Usage: tiny_impdef library.dll [-o outputfile]"
*
* Copyright (c) 2005,2007 grischka
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef TCC_TARGET_PE
ST_FUNC int tcc_tool_impdef(int argc, char **argv)
{
int ret, v, i;
char infile[260];
char outfile[260];
const char *file;
char *p, *q;
FILE *fp, *op;
#ifdef _WIN32
char path[260];
#endif
infile[0] = outfile[0] = 0;
fp = op = NULL;
ret = 1;
p = NULL;
v = 0;
for (i = 1; i < argc; ++i) {
const char *a = argv[i];
if ('-' == a[0]) {
if (0 == strcmp(a, "-v")) {
v = 1;
} else if (0 == strcmp(a, "-o")) {
if (++i == argc)
goto usage;
strcpy(outfile, argv[i]);
} else
goto usage;
} else if (0 == infile[0])
strcpy(infile, a);
else
goto usage;
}
if (0 == infile[0]) {
usage:
fprintf(stderr,
"usage: tcc -impdef library.dll [-v] [-o outputfile]\n"
"create export definition file (.def) from dll\n"
);
goto the_end;
}
if (0 == outfile[0]) {
strcpy(outfile, tcc_basename(infile));
q = strrchr(outfile, '.');
if (NULL == q)
q = strchr(outfile, 0);
strcpy(q, ".def");
}
file = infile;
#ifdef _WIN32
if (SearchPath(NULL, file, ".dll", sizeof path, path, NULL))
file = path;
#endif
ret = tcc_get_dllexports(file, &p);
if (ret || !p) {
fprintf(stderr, "tcc: impdef: %s '%s'\n",
ret == -1 ? "can't find file" :
ret == 1 ? "can't read symbols" :
ret == 0 ? "no symbols found in" :
"unknown file type", file);
ret = 1;
goto the_end;
}
if (v)
printf("-> %s\n", file);
op = fopen(outfile, "wb");
if (NULL == op) {
fprintf(stderr, "tcc: impdef: could not create output file: %s\n", outfile);
goto the_end;
}
fprintf(op, "LIBRARY %s\n\nEXPORTS\n", tcc_basename(file));
for (q = p, i = 0; *q; ++i) {
fprintf(op, "%s\n", q);
q += strlen(q) + 1;
}
if (v)
printf("<- %s (%d symbol%s)\n", outfile, i, &"s"[i<2]);
ret = 0;
the_end:
if (p)
tcc_free(p);
if (fp)
fclose(fp);
if (op)
fclose(op);
return ret;
}
#endif /* TCC_TARGET_PE */
/* -------------------------------------------------------------- */
/*
* TCC - Tiny C Compiler
*
* Copyright (c) 2001-2004 Fabrice Bellard
*
* This 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 of the License, or (at your option) any later version.
*
* This 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* re-execute the i386/x86_64 cross-compilers with tcc -m32/-m64: */
#if !defined TCC_TARGET_I386 && !defined TCC_TARGET_X86_64
ST_FUNC int tcc_tool_cross(char **argv, int option)
{
fprintf(stderr, "tcc -m%d not implemented\n", option);
return 1;
}
#else
#ifdef _WIN32
#include <process.h>
/* - Empty argument or with space/tab (not newline) requires quoting.
* - Double-quotes at the value require '\'-escape, regardless of quoting.
* - Consecutive (or 1) backslashes at the value all need '\'-escape only if
* followed by [escaped] double quote, else taken literally, e.g. <x\\y\>
* remains literal without quoting or esc, but <x\\"y\> becomes <x\\\\\"y\>.
* - This "before double quote" rule applies also before delimiting quoting,
* e.g. <x\y \"z\> becomes <"x\y \\\"z\\"> (quoting required because space).
*
* https://learn.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments
*/
static char *quote_win32(const char *s)
{
char *o, *r = tcc_malloc(2 * strlen(s) + 3); /* max-esc, quotes, \0 */
int cbs = 0, quoted = !*s; /* consecutive backslashes before current */
for (o = r; *s; *o++ = *s++) {
quoted |= *s == ' ' || *s == '\t';
if (*s == '\\' || *s == '"')
*o++ = '\\';
else
o -= cbs; /* undo cbs escapes, if any (not followed by DQ) */
cbs = *s == '\\' ? cbs + 1 : 0;
}
if (quoted) {
memmove(r + 1, r, o++ - r);
*r = *o++ = '"';
} else {
o -= cbs;
}
*o = 0;
return r; /* don't bother with realloc(r, o-r+1) */
}
static int execvp_win32(const char *prog, char **argv)
{
int ret; char **p;
/* replace all " by \" */
for (p = argv; *p; ++p)
*p = quote_win32(*p);
ret = _spawnvp(P_NOWAIT, prog, (const char *const*)argv);
if (-1 == ret)
return ret;
_cwait(&ret, ret, WAIT_CHILD);
exit(ret);
}
#define execvp execvp_win32
#endif /* _WIN32 */
ST_FUNC int tcc_tool_cross(char **argv, int target)
{
char program[4096];
char *a0 = argv[0];
int prefix = tcc_basename(a0) - a0;
snprintf(program, sizeof program,
"%.*s%s"
#ifdef TCC_TARGET_PE
"-win32"
#endif
"-tcc"
#ifdef _WIN32
".exe"
#endif
, prefix, a0, target == 64 ? "x86_64" : "i386");
if (strcmp(a0, program))
execvp(argv[0] = program, argv);
fprintf(stderr, "tcc: could not run '%s'\n", program);
return 1;
}
#endif /* TCC_TARGET_I386 && TCC_TARGET_X86_64 */
/* -------------------------------------------------------------- */
/* enable commandline wildcard expansion (tcc -o x.exe *.c) */
#ifdef _WIN32
const int _CRT_glob = 1;
#ifndef _CRT_glob
const int _dowildcard = 1;
#endif
#endif
/* -------------------------------------------------------------- */
/* generate xxx.d file */
static char *escape_target_dep(const char *s) {
char *res = tcc_malloc(strlen(s) * 2 + 1);
int j;
for (j = 0; *s; s++, j++) {
if (is_space(*s)) {
res[j++] = '\\';
}
res[j] = *s;
}
res[j] = '\0';
return res;
}
ST_FUNC int gen_makedeps(TCCState *s1, const char *target, const char *filename)
{
FILE *depout;
char buf[1024];
char **escaped_targets;
int i, k, num_targets;
if (!filename) {
/* compute filename automatically: dir/file.o -> dir/file.d */
snprintf(buf, sizeof buf, "%.*s.d",
(int)(tcc_fileextension(target) - target), target);
filename = buf;
}
if(!strcmp(filename, "-"))
depout = fdopen(1, "w");
else
/* XXX return err codes instead of error() ? */
depout = fopen(filename, "w");
if (!depout)
return tcc_error_noabort("could not open '%s'", filename);
if (s1->verbose)
printf("<- %s\n", filename);
escaped_targets = tcc_malloc(s1->nb_target_deps * sizeof(*escaped_targets));
num_targets = 0;
for (i = 0; i<s1->nb_target_deps; ++i) {
for (k = 0; k < i; ++k)
if (0 == strcmp(s1->target_deps[i], s1->target_deps[k]))
goto next;
escaped_targets[num_targets++] = escape_target_dep(s1->target_deps[i]);
next:;
}
fprintf(depout, "%s:", target);
for (i = 0; i < num_targets; ++i)
fprintf(depout, " \\\n %s", escaped_targets[i]);
fprintf(depout, "\n");
if (s1->gen_phony_deps) {
/* Skip first file, which is the c file.
* Only works for single file give on command-line,
* but other compilers have the same limitation */
for (i = 1; i < num_targets; ++i)
fprintf(depout, "%s:\n", escaped_targets[i]);
}
for (i = 0; i < num_targets; ++i)
tcc_free(escaped_targets[i]);
tcc_free(escaped_targets);
fclose(depout);
return 0;
}
/* -------------------------------------------------------------- */

13
tests/42test.h Normal file
View File

@ -0,0 +1,13 @@
/* This file is to test compute #include directives. It's named so
that it starts with a pre-processing number which isn't a valid
number (42test.h). Including this must work. */
#ifndef INC42_FIRST
int have_included_42test_h;
#define INC42_FIRST
#elif !defined INC42_SECOND
#define INC42_SECOND
int have_included_42test_h_second;
#else
#define INC42_THIRD
int have_included_42test_h_third;
#endif

351
tests/Makefile Normal file
View File

@ -0,0 +1,351 @@
#
# Tiny C Compiler Makefile - tests
#
TOP = ..
include $(TOP)/Makefile
VPATH = $(TOPSRC)/tests $(TOPSRC)
CFLAGS := $(filter-out -g% -O%,$(CFLAGS)) -I$(TOPSRC) -I$(TOP) $(LDFLAGS)
# what tests to run
TESTS = \
hello-exe \
hello-run \
libtest \
libtest_mt \
test3 \
abitest \
asm-c-connect-test \
vla_test-run \
tests2-dir \
pp-dir \
memtest \
dlltest \
cross-test
# test4_static -- Not all relocation types are implemented yet.
# asmtest / asmtest2 -- minor differences with gcc
ifeq ($(CONFIG_backtrace),no)
TESTS := $(filter-out libtest_mt, $(TESTS))
else ifneq ($(CONFIG_bcheck),no)
TESTS += btest test1b tccb
endif
ifeq ($(CONFIG_dll),no)
TESTS := $(filter-out dlltest, $(TESTS))
endif
ifeq (-$(CONFIG_arm_eabi)-$(CONFIG_arm_vfp)-,-yes--)
TESTS := $(filter-out test3 test1b,$(TESTS))
endif
ifeq (,$(filter i386 x86_64,$(ARCH)))
TESTS := $(filter-out asm-c-connect-test,$(TESTS))
endif
ifeq ($(OS),Windows_NT) # for libtcc_test to find libtcc.dll
PATH := $(CURDIR)/$(TOP)$(if $(findstring ;,$(PATH)),;,:)$(PATH)
endif
ifdef CONFIG_OSX
LIBS += $(LINK_LIBTCC)
endif
ifeq ($(ARCH),arm)
# tcctest refers to the alignment of functions, and with thumb mode
# the low bit of code addresses selects the mode, so the "alignment"
# of functions via bit masking comes out as 1. Just disable thumb.
test.ref: CFLAGS+=-marm
endif
ifeq ($(ARCH)$(CONFIG_WIN32),i386)
# tcctest.c:get_asm_string uses a construct that is checked too strictly
# by GCC in 32bit mode when PIC is enabled.
test.ref: CFLAGS+=-fno-PIC -fno-PIE -Wl,-z,notext
endif
ifeq ($(CC_NAME),msvc)
test.ref abitest : CC = gcc
endif
ifeq ($(TARGETOS),OpenBSD)
dlltest: CFLAGS+=-fno-stack-protector
endif
ifneq (,$(filter FreeBSD NetBSD,$(TARGETOS)))
# test3 has dlsym problems
TESTS := $(filter-out test3,$(TESTS))
TESTS += test1
endif
RUN_TCC = -run $(TOPSRC)/tcc.c $(TCCFLAGS)
DISAS = objdump -d
ifdef CONFIG_OSX
DUMPTCC = (set -x; $(TCC_LOCAL) -vv; otool -L $(TCC_LOCAL); exit 1)
else
DUMPTCC = (set -x; $(TCC_LOCAL) -vv; ldd $(TCC_LOCAL); exit 1)
endif
all test :
@echo ------------ version ------------
@$(TCC_LOCAL) -v
@$(MAKE) --no-print-directory -s clean
@$(MAKE) --no-print-directory -s -r _all
@echo ------- ALL TESTS PASSED --------
_all : $(TESTS)
hello-exe: ../examples/ex1.c
@echo ------------ $@ ------------
$(TCC) $< -o hello$(EXESUF) && ./hello$(EXESUF) || $(DUMPTCC)
hello-run: ../examples/ex1.c
@echo ------------ $@ ------------
$(TCC) -run $< || $(DUMPTCC)
libtes%: libtcc_tes%$(EXESUF)
@echo ------------ $@ ------------
./libtcc_tes$*$(EXESUF) $(TOPSRC)/tcc.c $(TCCFLAGS)
libtcc_test$(EXESUF): libtcc_test.c
$(CC) -o $@ $< $(CFLAGS) $(-LTCC) $(LIBS)
libtcc_test_mt$(EXESUF): libtcc_test_mt.c
$(CC) -o $@ $< $(CFLAGS) $(-LTCC) $(LIBS)
%-dir:
@echo ------------ $@ ------------
$(MAKE) -k -C $*
# test.ref - generate using cc
test.ref: tcctest.c
$(CC) -o tcctest.gcc$(EXESUF) $< $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer
./tcctest.gcc$(EXESUF) > $@
# auto test
test1 test1b: tcctest.c test.ref
@echo ------------ $@ ------------
$(TCC) $(RUN_TCC) -w -run $< > test.out1
@diff -u test.ref test.out1 && echo "$(AUTO_TEST) OK"
# iterated test2 (compile tcc then compile tcctest.c !)
test2 test2b: tcctest.c test.ref
@echo ------------ $@ ------------
$(TCC) $(RUN_TCC) $(RUN_TCC) -w -run $< > test.out2
@diff -u test.ref test.out2 && echo "$(AUTO_TEST)2 OK"
# iterated test3 (compile tcc then compile tcc then compile tcctest.c !)
test3 test3b: tcctest.c test.ref
@echo ------------ $@ ------------
$(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -w -run $< > test.out3
@diff -u test.ref test.out3 && echo "$(AUTO_TEST)3 OK"
AUTO_TEST = Auto Test
test%b : TCCFLAGS += -b -bt1
test%b : AUTO_TEST = Auto Bound-Test
# binary output test
test4: tcctest.c test.ref
@echo ------------ $@ ------------
# object + link output
$(TCC) -c -o tcctest3.o $<
$(TCC) -o tcctest3 tcctest3.o
./tcctest3 > test3.out
@if diff -u test.ref test3.out ; then echo "Object $(AUTO_TEST) OK"; fi
# dynamic output
$(TCC) -o tcctest1 $<
./tcctest1 > test1.out
@if diff -u test.ref test1.out ; then echo "Dynamic $(AUTO_TEST) OK"; fi
# dynamic output + bound check
$(TCC) -b -o tcctest4 $<
./tcctest4 > test4.out
@if diff -u test.ref test4.out ; then echo "BCheck $(AUTO_TEST) OK"; fi
test4_static: tcctest.c test.ref
@echo ------------ $@ ------------
# static output.
$(TCC) -static -o tcctest2 $<
./tcctest2 > test2.out
@if diff -u test.ref test2.out ; then echo "Static $(AUTO_TEST) OK"; fi
# use tcc to create libtcc.so/.dll and the tcc(.exe) frontend and run them
dlltest:
@echo ------------ $@ ------------
$(TCC) -DLIBTCC_AS_DLL $(TOPSRC)/libtcc.c $(LIBS) -shared -o libtcc2$(DLLSUF)
$(TCC) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF)
./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c
ifeq (,$(filter Darwin WIN32,$(TARGETOS)))
@echo ------------ $@ with PIC ------------
$(CC) $(CFLAGS) -fPIC -DLIBTCC_AS_DLL -c $(TOPSRC)/libtcc.c
$(TCC) libtcc.o $(LIBS) -shared -o libtcc2$(DLLSUF)
$(TCC) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF)
./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c
endif
@rm tcc2$(EXESUF) libtcc2$(DLLSUF)
memtest:
@echo ------------ $@ ------------
$(CC) $(CFLAGS) -DMEM_DEBUG=2 $(TOPSRC)/tcc.c $(LIBS) -o memtest-tcc$(EXESUF)
./memtest-tcc$(EXESUF) $(TCCFLAGS) $(TOPSRC)/tcc.c $(LIBS)
./memtest-tcc$(EXESUF) $(TCCFLAGS) -run $(TOPSRC)/tcc.c $(TCCFLAGS) -w $(TOPSRC)/tests/tcctest.c
@echo OK
# memory and bound check auto test
BOUNDS_OK = 1 4 8 10 14 16
BOUNDS_FAIL= 2 5 6 7 9 11 12 13 15 17 18
btest: boundtest.c
@echo ------------ $@ ------------
@for i in $(BOUNDS_OK); do \
if $(TCC) -b -run $< $$i >/dev/null 2>&1 ; then \
echo "Test $$i succeeded as expected" ; \
else\
echo "Failed positive test $$i" ; exit 1 ; \
fi ;\
done ;\
for i in $(BOUNDS_FAIL); do \
if $(TCC) -b -bt1 -run $< $$i >/dev/null 2>&1 ; then \
echo "Failed negative test $$i" ; exit 1 ;\
else\
echo "Test $$i failed as expected" ; \
fi ;\
done ;\
echo Bound-Test OK
tccb:
@echo ------------ $@ ------------
$(TCC) -b $(TOPSRC)/tcc.c $(TCCFLAGS) $(LIBS) -o tccb1.exe
mv tccb1.exe tccb2.exe
./tccb2.exe -b $(TOPSRC)/tcc.c $(TCCFLAGS) $(LIBS) -o tccb1.exe
cmp -s tccb1.exe tccb2.exe && echo "Exe Bound-Test OK"
# speed test
speedtest: ex2 ex3
@echo ------------ $@ ------------
time ./ex2 1238 2 3 4 10 13 4
time $(TCC) -run $(TOPSRC)/examples/ex2.c 1238 2 3 4 10 13 4
time ./ex3 35
time $(TCC) -run $(TOPSRC)/examples/ex3.c 35
weaktest: tcctest.c test.ref
@echo ------------ $@ ------------
$(TCC) -c $< -o weaktest.tcc.o
$(CC) -c $< -o weaktest.gcc.o $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer
objdump -t weaktest.tcc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.tcc.o.txt
objdump -t weaktest.gcc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.gcc.o.txt
diff weaktest.gcc.o.txt weaktest.tcc.o.txt && echo "Weak Auto Test OK"
ex%: $(TOPSRC)/examples/ex%.c
$(CC) -o $@ $< $(CFLAGS)
# tiny assembler testing
asmtest.ref: asmtest.S
$(CC) -Wa,-W -Wa,-mx86-used-note=no -o asmtest.ref.o -c asmtest.S
objdump -D asmtest.ref.o > asmtest.ref
ifeq ($(ARCH),arm)
asmtest asmtest2:
TCC="${TCC}" ./arm-asm-testsuite.sh
else
asmtest asmtest2: asmtest.ref
@echo ------------ $@ ------------
$(TCC) $(MAYBE_RUN_TCC) -c asmtest.S
objdump -D asmtest.o > asmtest.out
@if diff -u --ignore-matching-lines="file format" asmtest.ref asmtest.out ; then echo "ASM Auto Test OK"; fi
endif
# test assembler with tcc compiled by itself
asmtest2: MAYBE_RUN_TCC = $(RUN_TCC)
# Check that code generated by libtcc is binary compatible with
# that generated by CC
abitest-cc.exe: abitest.c
$(CC) -o $@ $^ $(CFLAGS) $(-LTCC) $(LIBS) -w
abitest-tcc.exe: abitest.c libtcc.c
$(TCC) -o $@ $^ $(LIBS)
abitest-% : abitest-%.exe
@echo ------------ $@ ------------
./$< $(TCCFLAGS)
abitest: abitest-cc
ifneq (-$(CONFIG_arm_eabi)-$(CONFIG_arm_vfp)-,-yes--)
abitest: abitest-tcc
endif
vla_test$(EXESUF): vla_test.c
$(TCC) -o $@ $^
vla_test-run: vla_test$(EXESUF)
@echo ------------ $@ ------------
./vla_test$(EXESUF)
.PHONY: abitest vla_test tccb
asm-c-connect$(EXESUF): asm-c-connect-1.c asm-c-connect-2.c
$(TCC) -o $@ $^
asm-c-connect-%.o: asm-c-connect-%.c
$(TCC) -c -o $@ $<
asm-c-connect-sep$(EXESUF): asm-c-connect-1.o asm-c-connect-2.o
$(TCC) -o $@ $^
asm-c-connect-test: asm-c-connect$(EXESUF) asm-c-connect-sep$(EXESUF)
@echo ------------ $@ ------------
./asm-c-connect$(EXESUF) > asm-c-connect.out1 && cat asm-c-connect.out1
./asm-c-connect-sep$(EXESUF) > asm-c-connect.out2 && cat asm-c-connect.out2
@diff -u asm-c-connect.out1 asm-c-connect.out2 || (echo "error"; exit 1)
# quick sanity check for cross-compilers
cross-test : tcctest.c examples/ex3.c
@echo ------------ $@ ------------
$(foreach T,$(CROSS-TGTS),$(call CROSS-COMPILE,$T))
CROSS-TGTS = \
i386 \
i386-win32 \
i386-OpenBSD \
x86_64 \
x86_64-win32 \
x86_64-osx \
x86_64-FreeBSD \
x86_64-NetBSD \
x86_64-OpenBSD \
arm-fpa \
arm-eabihf \
arm-NetBSD \
arm-wince \
arm64 \
arm64-win32 \
arm64-osx \
arm64-FreeBSD \
arm64-NetBSD \
arm64-OpenBSD \
riscv64 \
c67
define CROSS-COMPILE
@echo " . $(1)"
$(TCC) $(DEF-$1) -DTCC_CROSS_TEST -run $(TOPSRC)/tcc.c \
-c $(if $(findstring c67,$1),$(filter %/ex3.c,$^),$<) -w $(TCCFLAGS)
endef
# targets for development
%.bin: %.c tcc
$(TCC) -g -o $@ $<
$(DISAS) $@
instr: instr.o
objdump -d instr.o
instr.o: instr.S
$(CC) -o $@ -c $< -O2 -Wall -g
cache: tcc_g
cachegrind ./tcc_g -o /tmp/linpack -lm bench/linpack.c
vg_annotate tcc.c > /tmp/linpack.cache.log
# clean
clean:
rm -f *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.cc *.gcc
rm -f *-cc *-gcc *-tcc *.exe hello libtcc_test vla_test tcctest[1234]
rm -f asm-c-connect asm-c-connect-sep
rm -f ex? tcc_g weaktest.*.txt *.def *.pdb *.obj libtcc_test_mt
@$(MAKE) -C tests2 $@
@$(MAKE) -C pp $@

691
tests/abitest.c Normal file
View File

@ -0,0 +1,691 @@
#include <libtcc.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
// MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC
#if defined(_WIN32) && defined(__GNUC__)
#define LONG_DOUBLE double
#define LONG_DOUBLE_LITERAL(x) x
#else
#define LONG_DOUBLE long double
#define LONG_DOUBLE_LITERAL(x) x ## L
#endif
static int g_argc;
static char **g_argv;
static void set_options(TCCState *s, int argc, char **argv)
{
int i;
for (i = 1; i < argc; ++i) {
char *a = argv[i];
if (a[0] == '-') {
if (a[1] == 'B')
tcc_set_lib_path(s, a+2);
else if (a[1] == 'I')
tcc_add_include_path(s, a+2);
else if (a[1] == 'L')
tcc_add_library_path(s, a+2);
}
}
}
typedef int (*callback_type) (void*);
/*
* Compile source code and call a callback with a pointer to the symbol "f".
*/
static int run_callback(const char *src, callback_type callback) {
TCCState *s;
int result;
void *ptr;
s = tcc_new();
if (!s)
return -1;
set_options(s, g_argc, g_argv);
if (tcc_set_output_type(s, TCC_OUTPUT_MEMORY) == -1)
return -1;
if (tcc_compile_string(s, src) == -1)
return -1;
if (tcc_relocate(s) == -1)
return -1;
ptr = tcc_get_symbol(s, "f");
if (!ptr)
return -1;
result = callback(ptr);
tcc_delete(s);
return result;
}
#define STR2(x) #x
#define STR(x) STR2(x)
#define RET_PRIMITIVE_TEST(name, type, val) \
static int ret_ ## name ## _test_callback(void *ptr) { \
type (*callback) (type) = (type(*)(type))ptr; \
type x = val; \
type y = callback(x); \
return (y == x+x) ? 0 : -1; \
} \
\
static int ret_ ## name ## _test(void) { \
const char *src = STR(type) " f(" STR(type) " x) {return x+x;}"; \
return run_callback(src, ret_ ## name ## _test_callback); \
}
RET_PRIMITIVE_TEST(int, int, 70000)
RET_PRIMITIVE_TEST(longlong, long long, 4333369356528LL)
RET_PRIMITIVE_TEST(float, float, 63.0)
RET_PRIMITIVE_TEST(double, double, 14789798.0)
RET_PRIMITIVE_TEST(longdouble, LONG_DOUBLE, LONG_DOUBLE_LITERAL(378943892.0))
/*
* ret_2float_test:
*
* On x86-64, a struct with 2 floats should be packed into a single
* SSE register (VT_DOUBLE is used for this purpose).
*/
typedef struct ret_2float_test_type_s {float x, y;} ret_2float_test_type;
typedef ret_2float_test_type (*ret_2float_test_function_type) (ret_2float_test_type);
static int ret_2float_test_callback(void *ptr) {
ret_2float_test_function_type f = (ret_2float_test_function_type)ptr;
ret_2float_test_type a = {10, 35};
ret_2float_test_type r;
r = f(a);
return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
}
static int ret_2float_test(void) {
const char *src =
"typedef struct ret_2float_test_type_s {float x, y;} ret_2float_test_type;"
"ret_2float_test_type f(ret_2float_test_type a) {\n"
" ret_2float_test_type r = {a.x*5, a.y*3};\n"
" return r;\n"
"}\n";
return run_callback(src, ret_2float_test_callback);
}
/*
* ret_2double_test:
*
* On x86-64, a struct with 2 doubles should be passed in two SSE
* registers.
*/
typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;
typedef ret_2double_test_type (*ret_2double_test_function_type) (ret_2double_test_type);
static int ret_2double_test_callback(void *ptr) {
ret_2double_test_function_type f = (ret_2double_test_function_type)ptr;
ret_2double_test_type a = {10, 35};
ret_2double_test_type r;
r = f(a);
return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
}
static int ret_2double_test(void) {
const char *src =
"typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;"
"ret_2double_test_type f(ret_2double_test_type a) {\n"
" ret_2double_test_type r = {a.x*5, a.y*3};\n"
" return r;\n"
"}\n";
return run_callback(src, ret_2double_test_callback);
}
/*
* ret_8plus2double_test:
*
* This catches a corner case in the x86_64 ABI code: the first 7
* arguments fit into registers, the 8th doesn't, but the 9th argument
* fits into the 8th XMM register.
*
* Note that the purpose of the 10th argument is to avoid a situation
* in which gcc would accidentally put the double at the right
* address, thus causing a success message even though TCC actually
* generated incorrect code.
*/
typedef ret_2double_test_type (*ret_8plus2double_test_function_type) (double, double, double, double, double, double, double, ret_2double_test_type, double, double);
static int ret_8plus2double_test_callback(void *ptr) {
ret_8plus2double_test_function_type f = (ret_8plus2double_test_function_type)ptr;
ret_2double_test_type a = {10, 35};
ret_2double_test_type r;
r = f(0, 0, 0, 0, 0, 0, 0, a, 37, 38);
return ((r.x == 37) && (r.y == 37)) ? 0 : -1;
}
static int ret_8plus2double_test(void) {
const char *src =
"typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;"
"ret_2double_test_type f(double x1, double x2, double x3, double x4, double x5, double x6, double x7, ret_2double_test_type a, double x8, double x9) {\n"
" ret_2double_test_type r = { x8, x8 };\n"
" return r;\n"
"}\n";
return run_callback(src, ret_8plus2double_test_callback);
}
/*
* ret_mixed_test:
*
* On x86-64, a struct with a double and a 64-bit integer should be
* passed in one SSE register and one integer register.
*/
typedef struct ret_mixed_test_type_s {double x; long long y;} ret_mixed_test_type;
typedef ret_mixed_test_type (*ret_mixed_test_function_type) (ret_mixed_test_type);
static int ret_mixed_test_callback(void *ptr) {
ret_mixed_test_function_type f = (ret_mixed_test_function_type)ptr;
ret_mixed_test_type a = {10, 35};
ret_mixed_test_type r;
r = f(a);
return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
}
static int ret_mixed_test(void) {
const char *src =
"typedef struct ret_mixed_test_type_s {double x; long long y;} ret_mixed_test_type;"
"ret_mixed_test_type f(ret_mixed_test_type a) {\n"
" ret_mixed_test_type r = {a.x*5, a.y*3};\n"
" return r;\n"
"}\n";
return run_callback(src, ret_mixed_test_callback);
}
/*
* ret_mixed2_test:
*
* On x86-64, a struct with two floats and two 32-bit integers should
* be passed in one SSE register and one integer register.
*/
typedef struct ret_mixed2_test_type_s {float x,x2; int y,y2;} ret_mixed2_test_type;
typedef ret_mixed2_test_type (*ret_mixed2_test_function_type) (ret_mixed2_test_type);
static int ret_mixed2_test_callback(void *ptr) {
ret_mixed2_test_function_type f = (ret_mixed2_test_function_type)ptr;
ret_mixed2_test_type a = {10, 5, 35, 7 };
ret_mixed2_test_type r;
r = f(a);
return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
}
static int ret_mixed2_test(void) {
const char *src =
"typedef struct ret_mixed2_test_type_s {float x, x2; int y,y2;} ret_mixed2_test_type;"
"ret_mixed2_test_type f(ret_mixed2_test_type a) {\n"
" ret_mixed2_test_type r = {a.x*5, 0, a.y*3, 0};\n"
" return r;\n"
"}\n";
return run_callback(src, ret_mixed2_test_callback);
}
/*
* ret_mixed3_test:
*
* On x86-64, this struct should be passed in two integer registers.
*/
typedef struct ret_mixed3_test_type_s {float x; int y; float x2; int y2;} ret_mixed3_test_type;
typedef ret_mixed3_test_type (*ret_mixed3_test_function_type) (ret_mixed3_test_type);
static int ret_mixed3_test_callback(void *ptr) {
ret_mixed3_test_function_type f = (ret_mixed3_test_function_type)ptr;
ret_mixed3_test_type a = {10, 5, 35, 7 };
ret_mixed3_test_type r;
r = f(a);
return ((r.x == a.x*5) && (r.y2 == a.y*3)) ? 0 : -1;
}
static int ret_mixed3_test(void) {
const char *src =
"typedef struct ret_mixed3_test_type_s {float x; int y; float x2; int y2;} ret_mixed3_test_type;"
"ret_mixed3_test_type f(ret_mixed3_test_type a) {\n"
" ret_mixed3_test_type r = {a.x*5, 0, 0, a.y*3};\n"
" return r;\n"
"}\n";
return run_callback(src, ret_mixed3_test_callback);
}
/*
* reg_pack_test: return a small struct which should be packed into
* registers (Win32) during return.
*/
typedef struct reg_pack_test_type_s {int x, y;} reg_pack_test_type;
typedef reg_pack_test_type (*reg_pack_test_function_type) (reg_pack_test_type);
static int reg_pack_test_callback(void *ptr) {
reg_pack_test_function_type f = (reg_pack_test_function_type)ptr;
reg_pack_test_type a = {10, 35};
reg_pack_test_type r;
r = f(a);
return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
}
static int reg_pack_test(void) {
const char *src =
"typedef struct reg_pack_test_type_s {int x, y;} reg_pack_test_type;"
"reg_pack_test_type f(reg_pack_test_type a) {\n"
" reg_pack_test_type r = {a.x*5, a.y*3};\n"
" return r;\n"
"}\n";
return run_callback(src, reg_pack_test_callback);
}
/*
* reg_pack_longlong_test: return a small struct which should be packed into
* registers (x86-64) during return.
*/
typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;
typedef reg_pack_longlong_test_type (*reg_pack_longlong_test_function_type) (reg_pack_longlong_test_type);
static int reg_pack_longlong_test_callback(void *ptr) {
reg_pack_longlong_test_function_type f = (reg_pack_longlong_test_function_type)ptr;
reg_pack_longlong_test_type a = {10, 35};
reg_pack_longlong_test_type r;
r = f(a);
return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
}
static int reg_pack_longlong_test(void) {
const char *src =
"typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;"
"reg_pack_longlong_test_type f(reg_pack_longlong_test_type a) {\n"
" reg_pack_longlong_test_type r = {a.x*5, a.y*3};\n"
" return r;\n"
"}\n";
return run_callback(src, reg_pack_longlong_test_callback);
}
/*
* ret_6plus2longlong_test:
*
* This catches a corner case in the x86_64 ABI code: the first 5
* arguments fit into registers, the 6th doesn't, but the 7th argument
* fits into the 6th argument integer register, %r9.
*
* Note that the purpose of the 10th argument is to avoid a situation
* in which gcc would accidentally put the longlong at the right
* address, thus causing a success message even though TCC actually
* generated incorrect code.
*/
typedef reg_pack_longlong_test_type (*ret_6plus2longlong_test_function_type) (long long, long long, long long, long long, long long, reg_pack_longlong_test_type, long long, long long);
static int ret_6plus2longlong_test_callback(void *ptr) {
ret_6plus2longlong_test_function_type f = (ret_6plus2longlong_test_function_type)ptr;
reg_pack_longlong_test_type a = {10, 35};
reg_pack_longlong_test_type r;
r = f(0, 0, 0, 0, 0, a, 37, 38);
return ((r.x == 37) && (r.y == 37)) ? 0 : -1;
}
static int ret_6plus2longlong_test(void) {
const char *src =
"typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;"
"reg_pack_longlong_test_type f(long long x1, long long x2, long long x3, long long x4, long long x5, reg_pack_longlong_test_type a, long long x8, long long x9) {\n"
" reg_pack_longlong_test_type r = { x8, x8 };\n"
" return r;\n"
"}\n";
return run_callback(src, ret_6plus2longlong_test_callback);
}
/*
* sret_test: Create a struct large enough to be returned via sret
* (hidden pointer as first function argument)
*/
typedef struct sret_test_type_s {long long a, b, c;} sret_test_type;
typedef sret_test_type (*sret_test_function_type) (sret_test_type);
static int sret_test_callback(void *ptr) {
sret_test_function_type f = (sret_test_function_type)(ptr);
sret_test_type x = {5436LL, 658277698LL, 43878957LL};
sret_test_type r = f(x);
return ((r.a==x.a*35)&&(r.b==x.b*19)&&(r.c==x.c*21)) ? 0 : -1;
}
static int sret_test(void) {
const char *src =
"typedef struct sret_test_type_s {long long a, b, c;} sret_test_type;\n"
"sret_test_type f(sret_test_type x) {\n"
" sret_test_type r = {x.a*35, x.b*19, x.c*21};\n"
" return r;\n"
"}\n";
return run_callback(src, sret_test_callback);
}
/*
* one_member_union_test:
*
* In the x86-64 ABI a union should always be passed on the stack. However
* it appears that a single member union is treated by GCC as its member.
*/
typedef union one_member_union_test_type_u {int x;} one_member_union_test_type;
typedef one_member_union_test_type (*one_member_union_test_function_type) (one_member_union_test_type);
static int one_member_union_test_callback(void *ptr) {
one_member_union_test_function_type f = (one_member_union_test_function_type)ptr;
one_member_union_test_type a, b;
a.x = 34;
b = f(a);
return (b.x == a.x*2) ? 0 : -1;
}
static int one_member_union_test(void) {
const char *src =
"typedef union one_member_union_test_type_u {int x;} one_member_union_test_type;\n"
"one_member_union_test_type f(one_member_union_test_type a) {\n"
" one_member_union_test_type b;\n"
" b.x = a.x * 2;\n"
" return b;\n"
"}\n";
return run_callback(src, one_member_union_test_callback);
}
/*
* two_member_union_test:
*
* In the x86-64 ABI a union should always be passed on the stack.
*/
typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type;
typedef two_member_union_test_type (*two_member_union_test_function_type) (two_member_union_test_type);
static int two_member_union_test_callback(void *ptr) {
two_member_union_test_function_type f = (two_member_union_test_function_type)ptr;
two_member_union_test_type a, b;
a.x = 34;
b = f(a);
return (b.x == a.x*2) ? 0 : -1;
}
static int two_member_union_test(void) {
const char *src =
"typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type;\n"
"two_member_union_test_type f(two_member_union_test_type a) {\n"
" two_member_union_test_type b;\n"
" b.x = a.x * 2;\n"
" return b;\n"
"}\n";
return run_callback(src, two_member_union_test_callback);
}
/*
* Win64 calling convention test.
*/
typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;
typedef many_struct_test_type (*many_struct_test_function_type) (many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type);
static int many_struct_test_callback(void *ptr) {
many_struct_test_function_type f = (many_struct_test_function_type)ptr;
many_struct_test_type v = {1, 2, 3};
many_struct_test_type r = f(v,v,v,v,v,v);
return ((r.a == 6) && (r.b == 12) && (r.c == 18))?0:-1;
}
static int many_struct_test(void) {
const char *src =
"typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;\n"
"many_struct_test_type f(many_struct_test_type x1, many_struct_test_type x2, many_struct_test_type x3, many_struct_test_type x4, many_struct_test_type x5, many_struct_test_type x6) {\n"
" many_struct_test_type y;\n"
" y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n"
" y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n"
" y.c = x1.c + x2.c + x3.c + x4.c + x5.c + x6.c;\n"
" return y;\n"
"}\n";
return run_callback(src, many_struct_test_callback);
}
/*
* Win64 calling convention test.
*/
typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;
typedef many_struct_test_2_type (*many_struct_test_2_function_type) (many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type);
static int many_struct_test_2_callback(void *ptr) {
many_struct_test_2_function_type f = (many_struct_test_2_function_type)ptr;
many_struct_test_2_type v = {1,2};
many_struct_test_2_type r = f(v,v,v,v,v,v);
return ((r.a == 6) && (r.b == 12))?0:-1;
}
static int many_struct_test_2(void) {
const char *src =
"typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;\n"
"many_struct_test_2_type f(many_struct_test_2_type x1, many_struct_test_2_type x2, many_struct_test_2_type x3, many_struct_test_2_type x4, many_struct_test_2_type x5, many_struct_test_2_type x6) {\n"
" many_struct_test_2_type y;\n"
" y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n"
" y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n"
" return y;\n"
"}\n";
return run_callback(src, many_struct_test_2_callback);
}
/*
* Win64 calling convention test.
*/
typedef struct many_struct_test_3_type_s {int a, b;} many_struct_test_3_type;
typedef many_struct_test_3_type (*many_struct_test_3_function_type) (many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type, ...);
typedef struct many_struct_test_3_struct_type { many_struct_test_3_function_type f; many_struct_test_3_function_type *f2; } many_struct_test_3_struct_type;
static void many_struct_test_3_dummy(double d, ...)
{
volatile double x = d;
}
static int many_struct_test_3_callback(void *ptr) {
many_struct_test_3_struct_type s = { ptr, };
many_struct_test_3_struct_type *s2 = &s;
s2->f2 = &s2->f;
many_struct_test_3_dummy(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, &s2);
many_struct_test_3_function_type f = *(s2->f2);
many_struct_test_3_type v = {1,2};
many_struct_test_3_type r = (*((s2->f2=&f)+0))(v,v,v,v,v,v,1.0);
return ((r.a == 6) && (r.b == 12))?0:-1;
}
static int many_struct_test_3(void) {
const char *src =
"typedef struct many_struct_test_3_type_s {int a, b;} many_struct_test_3_type;\n"
"many_struct_test_3_type f(many_struct_test_3_type x1, many_struct_test_3_type x2, many_struct_test_3_type x3, many_struct_test_3_type x4, many_struct_test_3_type x5, many_struct_test_3_type x6, ...) {\n"
" many_struct_test_3_type y;\n"
" y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n"
" y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n"
" return y;\n"
"}\n";
return run_callback(src, many_struct_test_3_callback);
}
/*
* stdarg_test: Test variable argument list ABI
*/
typedef struct {long long a, b, c;} stdarg_test_struct_type;
typedef void (*stdarg_test_function_type) (int,int,int,...);
static int stdarg_test_callback(void *ptr) {
stdarg_test_function_type f = (stdarg_test_function_type)ptr;
int x;
double y;
stdarg_test_struct_type z = {1, 2, 3}, w;
f(10, 10, 5,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, &x,
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, &y,
z, z, z, z, z, &w);
return ((x == 55) && (y == 55) && (w.a == 5) && (w.b == 10) && (w.c == 15)) ? 0 : -1;
}
static int stdarg_test(void) {
const char *src =
"#include <stdarg.h>\n"
"typedef struct {long long a, b, c;} stdarg_test_struct_type;\n"
"void f(int n_int, int n_float, int n_struct, ...) {\n"
" int i, ti = 0;\n"
" double td = 0.0;\n"
" stdarg_test_struct_type ts = {0,0,0}, tmp;\n"
" va_list ap;\n"
" va_start(ap, n_struct);\n"
" for (i = 0, ti = 0; i < n_int; ++i)\n"
" ti += va_arg(ap, int);\n"
" *va_arg(ap, int*) = ti;\n"
" for (i = 0, td = 0; i < n_float; ++i)\n"
" td += va_arg(ap, double);\n"
" *va_arg(ap, double*) = td;\n"
" for (i = 0; i < n_struct; ++i) {\n"
" tmp = va_arg(ap, stdarg_test_struct_type);\n"
" ts.a += tmp.a; ts.b += tmp.b; ts.c += tmp.c;"
" }\n"
" *va_arg(ap, stdarg_test_struct_type*) = ts;\n"
" va_end(ap);"
"}\n";
return run_callback(src, stdarg_test_callback);
}
typedef struct {long long a, b;} stdarg_many_test_struct_type;
typedef void (*stdarg_many_test_function_type) (int, int, int, int, int,
stdarg_many_test_struct_type,
int, int, ...);
static int stdarg_many_test_callback(void *ptr)
{
stdarg_many_test_function_type f = (stdarg_many_test_function_type)ptr;
int x;
stdarg_many_test_struct_type l = {10, 11};
f(1, 2, 3, 4, 5, l, 6, 7, &x, 44);
return x == 44 ? 0 : -1;
}
static int stdarg_many_test(void)
{
const char *src =
"#include <stdarg.h>\n"
"typedef struct {long long a, b;} stdarg_many_test_struct_type;\n"
"void f (int a, int b, int c, int d, int e, stdarg_many_test_struct_type l, int f, int g, ...){\n"
" va_list ap;\n"
" int *p;\n"
" va_start (ap, g);\n"
" p = va_arg(ap, int*);\n"
" *p = va_arg(ap, int);\n"
" va_end (ap);\n"
"}\n";
return run_callback(src, stdarg_many_test_callback);
}
/*
* Test Win32 stdarg handling, since the calling convention will pass a pointer
* to the struct and the stdarg pointer must point to that pointer initially.
*/
typedef struct {long long a, b, c;} stdarg_struct_test_struct_type;
typedef int (*stdarg_struct_test_function_type) (stdarg_struct_test_struct_type a, ...);
static int stdarg_struct_test_callback(void *ptr) {
stdarg_struct_test_function_type f = (stdarg_struct_test_function_type)ptr;
stdarg_struct_test_struct_type v = {10, 35, 99};
int x = f(v, 234);
return (x == 378) ? 0 : -1;
}
static int stdarg_struct_test(void) {
const char *src =
"#include <stdarg.h>\n"
"typedef struct {long long a, b, c;} stdarg_struct_test_struct_type;\n"
"int f(stdarg_struct_test_struct_type a, ...) {\n"
" va_list ap;\n"
" va_start(ap, a);\n"
" int z = va_arg(ap, int);\n"
" va_end(ap);\n"
" return z + a.a + a.b + a.c;\n"
"}\n";
return run_callback(src, stdarg_struct_test_callback);
}
/* Test that x86-64 arranges the stack correctly for arguments with alignment >8 bytes */
typedef LONG_DOUBLE (*arg_align_test_callback_type) (LONG_DOUBLE,int,LONG_DOUBLE,int,LONG_DOUBLE);
static int arg_align_test_callback(void *ptr) {
arg_align_test_callback_type f = (arg_align_test_callback_type)ptr;
long double x = f(12, 0, 25, 0, 37);
return (x == 74) ? 0 : -1;
}
static int arg_align_test(void) {
const char *src =
"long double f(long double a, int b, long double c, int d, long double e) {\n"
" return a + c + e;\n"
"}\n";
return run_callback(src, arg_align_test_callback);
}
#define RUN_TEST(t) \
if (!testname || (strcmp(#t, testname) == 0)) { \
fputs(#t "... ", stdout); \
fflush(stdout); \
if (t() == 0) { \
fputs("success\n", stdout); \
} else { \
fputs("failure\n", stdout); \
retval = EXIT_FAILURE; \
} \
}
int main(int argc, char **argv) {
int i;
const char *testname = NULL;
int retval = EXIT_SUCCESS;
/* if tcclib.h and libtcc1.a are not installed, where can we find them */
for (i = 1; i < argc; ++i) {
if (!memcmp(argv[i], "run_test=", 9))
testname = argv[i] + 9;
}
g_argv = argv, g_argc = argc;
RUN_TEST(ret_int_test);
RUN_TEST(ret_longlong_test);
RUN_TEST(ret_float_test);
RUN_TEST(ret_double_test);
RUN_TEST(ret_longdouble_test);
RUN_TEST(ret_2float_test);
RUN_TEST(ret_2double_test);
RUN_TEST(ret_8plus2double_test);
RUN_TEST(ret_6plus2longlong_test);
#if !defined __x86_64__ || defined _WIN32
/* currently broken on x86_64 linux */
RUN_TEST(ret_mixed_test);
RUN_TEST(ret_mixed2_test);
#endif
RUN_TEST(ret_mixed3_test);
RUN_TEST(reg_pack_test);
RUN_TEST(reg_pack_longlong_test);
RUN_TEST(sret_test);
RUN_TEST(one_member_union_test);
RUN_TEST(two_member_union_test);
RUN_TEST(many_struct_test);
RUN_TEST(many_struct_test_2);
RUN_TEST(many_struct_test_3);
RUN_TEST(stdarg_test);
RUN_TEST(stdarg_many_test);
RUN_TEST(stdarg_struct_test);
RUN_TEST(arg_align_test);
return retval;
}

Some files were not shown because too many files have changed in this diff Show More