[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Tinycc-devel] Why does TinyCC fail to link standard C runtime functions
From: |
Fereydoun Memarzanjany |
Subject: |
[Tinycc-devel] Why does TinyCC fail to link standard C runtime functions in 32-bit mode but works in 64-bit mode? |
Date: |
Sun, 24 Nov 2024 10:42:40 -0700 |
If you use TinyCC in its 32-bit mode (`-m32`) to compile a sample
program that uses any CRT function/symbol from `msvcrt.dll` (such as
the snippet provided later in this message), you'll be met with
compilation failures:
`tcc.exe -std=c11 -Wall -Werror -Wl,-subsystem=console -m32 .\main.c`
"tcc: error: undefined symbol '_iob', missing __declspec(dllimport)?"
(This only happens under `-m32`, whereas `-m64` works perfectly fine.)
`_iob` is not the only "unresolved" symbol, either; `printf`,
`freopen`, `freopen_s`, and basically everything from the CRT will
fail to link.
Regardless of whether or not you use `-lmsvcrt`, `#pragma comment(lib,
"msvcrt")`, `_declspec(dllimport)`, `attribute ((dllimport))`,
`-static` or `-shared`, or even `-impdef` on
"C:\Windows\SysWow64\msvcrt.dll" (or earlier versions thereof:
"msvcrt40.dll"), TCC still complains.
I've verified with `DUMPBIN.exe` that both 32- and 64-bit "msvcrt.dll"
do, in fact, define `_iob` and other symbols.
By some arcane logic, the following works perfectly fine: `tcc.exe
-std=c11 -Wall -Werror -Wl,-subsystem=console -m64 .\main.c`
`main.c`
```c
//#pragma comment(lib, "msvcrt")
//__attribute__((dllimport)) extern __declspec(dllimport) FILE _iob[];
#include <windows.h>
// _MSVCRT_ being defined will cause MinGW's stdio.h to use _iob as
// opposed to _imp___iob; only the former is defined in msvcrt.dll.
// However, even though _iob is exported by both the 32- and 64-bit
// versions of said dll, TinyCC still fails to find _iob in the former.
#define _MSVCRT_
#include <stdio.h>
void main() {
// AllocConsole() and basically everything from kernel32.dll or
// user32.dll work perfectly fine, both in -m32 and -m64; it's
// only msvcrt.dll that causes issues with TinyCC.
AllocConsole();
// Any CRT function (e.g., freopen, freopen_s, printf, etc.)
// fail to get linked properly ONLY in -m32; -m64 is fine.
// Even if I change the -I and -L paths to C:/Windows/SysWow64
// and/or use tcc.exe -impdef to create .def files from them,
// TCC still fails in finding _iob and other symbols.
// Also, using #pragma comment(lib, "msvcrt") or -lmsvcrt
// doesn't help at all. Even if you do get TCC to somehow
// stop complaining about missing symbols, it'd just include
// a blank IAT.printf or IAT.freopen, causing segfaults.
freopen("CONOUT$", "w", stdout);
printf("This only compiles (and prints) under TCC in 64-bit mode.");
}
```
As mentioned earlier, this error in `-m32` happens regardless of other
switches like `-std`, `-shared`, `-static`, `-lmsvcrt`, `-subsyetem`,
etc. So, at this point, I'm starting to think this might really be a
bug with TinyCC 0.9.27 (Win32 & Win64 builds) itself.
- [Tinycc-devel] Why does TinyCC fail to link standard C runtime functions in 32-bit mode but works in 64-bit mode?,
Fereydoun Memarzanjany <=
Re: [Tinycc-devel] Why does TinyCC fail to link standard C runtime functions in 32-bit mode but works in 64-bit mode?, avih, 2024/11/24