Hi there, I've made the patch in my local branch and the tests. Hope it's usefull.
Following are the test commands you may use. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ _tmain: ---------------------------------------------------- tcc.exe test_tmain.c -D_UNICODE &&test_tmain tcc.exe test_tmain.c &&test_tmain tcc.exe test_tmain.c -D_UNICODE -run tcc.exe test_tmain.c -run ---------------------------------------------------- _tWinMain: ----------------------------------------------------------------------- -D_UNICODE for _tWinMain -*-> wWinMain -DUNICODE for LPTSTR --> TCHAR -*-> WCHAR --> wchar_t ASCI: LPTSTR --> TCHAR ---> CHAR --> char LPWSTR --> WCHAR --> wchar_t LPSTR --> CHAR --> char ..........................................................................................................tcc.exe test_tWinMain.c -D_UNICODE -DUNICODE -luser32 && test_tWinMain "Show me!"
tcc.exe test_tWinMain.c -luser32 && test_tWinMain "Show me!" tcc.exe test_tWinMain.c -D_UNICODE -DUNICODE -luser32 -run tcc.exe test_tWinMain.c -luser32 -run ----------------------------------------------------------------------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Also, my analysis notes file is attached. It could be a little different as it is generated from my issue branch.
And as in the last section, the referred "spliting of the crt files", do you have any interest? Do you have any other ideas?
Regards, YX Hao
commit-28b6740
Description: Binary data
***********************************************
For _tmain:
findstr /s /n /r /c:"[^a-zA-Z][w]*main[^a-zA-Z]" *.c
-----------------------------------------------
arm-gen.c:902: See the comment for the main loop in copy_params() for the
reason. */
-----------------------------------------------
conftest.c:44:int main(int argc, char *argv[])
-----------------------------------------------
il-gen.c:434: if (!strcmp(funcname, "main"))
if (!strcmp(funcname, "main"))
fprintf(il_outfile, " .entrypoint\n");
??? who/where/which platform uses this?
-----------------------------------------------
lib\bcheck.c:421:void __bound_main_arg(void **p)
-----------------------------------------------
libtcc.c:1047: s->runtime_main = "main";
for tcc_new() ... add a flag "unicode_mode"
......
tcc.h
..............................................
#ifdef TCC_TARGET_PE
/* PE info */
int pe_subsystem;
unsigned pe_file_align;
unsigned pe_stack_size;
# ifdef TCC_TARGET_X86_64
Section *uw_pdata;
int uw_sym;
unsigned uw_offs;
# endif
int unicode_mode; /* _tmain, _tWinMain */
#endif
..............................................
#ifdef TCC_IS_NATIVE
s->runtime_main = "main";
#endif
#ifdef TCC_TARGET_PE
s->unicode_mode = 0;
#endif
return s;
..............................................
-----------------------------------------------
tcc.c:244:int main(int argc, char **argv)
-----------------------------------------------
*** not for TCC_TARGET_COFF
tcccoff.c:46:int C67_main_entry_point;
tcccoff.c:108: o_filehdr.entrypt = C67_main_entry_point; /* entry pt.
*/
tcccoff.c:931: // strip off any leading underscore (except for other main
routine)
-----------------------------------------------
tcccoff.c:933: if (name[0] == '_' && strcmp(name, "_main") != 0)
?
ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
{
xxx-unknown
..............................................
// strip off any leading underscore (except for other main routine)
if (name[0] == '_'
&& (strcmp(name, s1->unicode_mode == 0 ? "_main" : "_wmain") != 0))
name++;
/* skip unused (undefined) */ /* Need or not? */
if ((s1->unicode_mode == 0 && strcmp(name, "wmain") != 0)
|| (s1->unicode_mode && strcmp(name, "main") != 0))
tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value);
}
..............................................
tcc_add_symbol [---> (TCC_TARGET_PE) pe_putimport] --->| add_elf_sym
-----------------------------------------------
tccgen.c:5827: && !strcmp(get_tok_str(sym->v, NULL), "main")) {
??? compilation stage
..............................................
#ifdef CONFIG_TCC_BCHECK
if (tcc_state->do_bounds_check
&& (!strcmp(get_tok_str(sym->v, NULL),
#ifdef TCC_TARGET_PE
tcc_state->unicode_entry == 3 /*PE_EXE*/ ? "wmain" :
//tcc_state->unicode_entry == 2 /*PE_GUI*/ ? PE_STDSYM("wWinMain","@16")
:
//tcc_state->pe_subsystem == 2 /*PE_GUI*/ ? PE_STDSYM("WinMain","@16") :
#endif
"main"))) {
int i;
sym = local_stack;
for (i = 0, sym = local_stack; i < 2; i++, sym = sym->prev) {
if (sym->v & SYM_FIELD || sym->prev->v & SYM_FIELD)
break;
vpush_global_sym(&func_old_type, TOK___bound_main_arg);
vset(&sym->type, sym->r, sym->c);
gfunc_call(1);
}
}
#endif
..............................................
-----------------------------------------------
tccgen.c:5834: vpush_global_sym(&func_old_type,
TOK___bound_main_arg);
-----------------------------------------------
tccpe.c:1759: ? PE_GUI == pe_type ? "__runwinmain" : wconsole == 0 ? "_main" :
"_wmain"
tccpe.c:1793: s1->runtime_main = start_symbol;
static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
{
..............................................
else {
pe_type = PE_EXE;
if (find_elf_sym(symtab_section, "wmain"))
s1->unicode_mode = 1;
}
..............................................
if (TCC_OUTPUT_MEMORY == s1->output_type) {
pe_type = PE_RUN;
#ifdef TCC_IS_NATIVE
s1->runtime_main = start_symbol;
#endif
} else {
pe->start_addr = (DWORD)(uintptr_t)tcc_get_symbol_err(s1, start_symbol);
}
..............................................
start_symbol =
TCC_OUTPUT_MEMORY == s1->output_type
? PE_GUI == pe_type ? "__runwinmain" : s1->unicode_mode ? "_wmain" :
"_main"
: PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12")
: PE_GUI == pe_type ? "__winstart" : s1->unicode_mode ? "__wstart" :
"__start"
;
..............................................
(tccpe.c) pe_add_runtime --->
(libtcc.c) tcc_add_library ---> tcc_add_library_internal --->
tcc_add_file_internal --->
(tccelf.c) [tcc_load_archive --->] tcc_load_object_file --->| add_elf_sym
++ tccelf.c
..............................................
#ifdef TCC_TARGET_PE
#ifdef TCC_TARGET_X86_64
#define PE_STDSYM(n,s) n
#else
#define PE_STDSYM(n,s) "_" n s
#endif
#endif
..............................................
ST_FUNC int tcc_load_object_file(TCCState *s1,
int fd, unsigned long file_offset)
{
..............................................
/* add symbol */
name = (char *) strtab + sym->st_name;
#ifdef TCC_TARGET_PE
/* skip unused (undefined) */
int unicode_mode = s1->unicode_mode;
if ((unicode_mode && strcmp(name, "main") != 0)
|| (unicode_mode == 0 && strcmp(name, "wmain") != 0))
#endif
sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
sym->st_info, sym->st_other,
sym->st_shndx, name);
old_to_new_syms[i] = sym_index;
..............................................
-----------------------------------------------
tccrun.c:29:ST_DATA void *rt_prog_main;
tccrun.c:94: int (*prog_main)(int, char **);
tccrun.c:100: prog_main = tcc_get_symbol_err(s1, s1->runtime_main);
-----------------------------------------------
tccrun.c:105: rt_prog_main = prog_main;
tccrun.c:130: ret = (*prog_main)(argc, argv);
tccrun.c:140: ret = (*prog_main)(argc, argv);
tccrun.c:406: if (pc == (addr_t)rt_prog_main && pc)
-----------------------------------------------
win32\lib\crt1.c:19:int main(int argc, char **argv, char **env);
win32\lib\crt1.c:33: ret = main(argc, argv, env);
+++
For ExitProcess, Add "#include <windows.h>".
===============================================
"add_elf_sym" is used in many other cases!
So, the skipping judgement placed out of it and only for win.
===============================================
-----------------------------------------------
win32\tools\tiny_impdef.c:47:int main(int argc, char **argv)
win32\tools\tiny_libmaker.c:74:int main(int argc, char **argv)
examples\ex1.c:4:int main()
examples\ex2.c:67:int main(int argc, char **argv)
examples\ex3.c:12:int main(int argc, char **argv)
examples\ex4.c:8:int main(int argc, char **argv)
examples\ex5.c:4:int main()
tests\abitest.c:422:int main(int argc, char **argv) {
tests\boundtest.c:208:int main(int argc, char **argv)
tests\libtcc_test.c:35:int main(int argc, char **argv)
tests\tcctest.c:636:int main(int argc, char **argv)
tests\tests2\00_assignment.c:3:int main()
tests\tests2\01_comment.c:3:int main()
tests\tests2\02_printf.c:3:int main()
tests\tests2\03_struct.c:9:int main()
tests\tests2\04_for.c:3:int main()
tests\tests2\05_array.c:3:int main()
tests\tests2\06_case.c:3:int main()
tests\tests2\07_function.c:18:int main()
tests\tests2\08_while.c:3:int main()
tests\tests2\09_do_while.c:3:int main()
tests\tests2\10_pointer.c:10:int main()
tests\tests2\11_precedence.c:3:int main()
tests\tests2\12_hashdefine.c:6:int main()
tests\tests2\13_integer_literals.c:3:int main()
tests\tests2\14_if.c:3:int main()
tests\tests2\15_recursion.c:11:int main()
tests\tests2\16_nesting.c:3:int main()
tests\tests2\17_enum.c:15:int main()
tests\tests2\18_include.c:3:int main()
tests\tests2\19_pointer_arithmetic.c:3:int main()
tests\tests2\20_pointer_comparison.c:3:int main()
tests\tests2\21_char_array.c:3:int main()
tests\tests2\22_floating_point.c:4:int main()
tests\tests2\23_type_coercion.c:18:int main()
tests\tests2\24_math_library.c:4:int main()
tests\tests2\25_quicksort.c:47:int main()
tests\tests2\26_character_constants.c:3:int main()
tests\tests2\27_sizeof.c:3:int main()
tests\tests2\28_strings.c:5:int main()
tests\tests2\29_array_address.c:4:int main()
tests\tests2\30_hanoi.c:100:int main()
tests\tests2\31_args.c:3:int main(int argc, char **argv)
tests\tests2\32_led.c:224:int main()
tests\tests2\32_led.c:234:int main(int argc, char **argv)
tests\tests2\33_ternary_op.c:3:int main()
tests\tests2\34_array_assignment.c:3:int main()
tests\tests2\35_sizeof.c:3:int main()
tests\tests2\36_array_initialisers.c:3:int main()
tests\tests2\37_sprintf.c:3:int main()
tests\tests2\38_multiple_array_index.c:3:int main()
tests\tests2\39_typedef.c:15:int main()
tests\tests2\40_stdio.c:3:int main()
tests\tests2\41_hashif.c:3:int main()
tests\tests2\42_function_pointer.c:11:int main()
tests\tests2\43_void_param.c:8:int main()
tests\tests2\44_scoped_declarations.c:3:int main()
tests\tests2\45_empty_for.c:3:int main()
tests\tests2\46_grep.c:481:int main(int argc, char **argv)
tests\tests2\47_switch_return.c:15:int main()
tests\tests2\48_nested_break.c:3:int main()
tests\tests2\49_bracket_evaluation.c:11:int main()
tests\tests2\50_logical_second_arg.c:15:int main()
tests\tests2\51_static.c:14:int main()
tests\tests2\52_unnamed_enum.c:5:int main()
tests\tests2\54_goto.c:47:int main()
tests\tests2\55_lshift_type.c:45:int main (int argc, char **argv)
tests\tests2\63_local_enumerator_redefinition.c:6:int main(void)
tests\tests2\64_macro_nesting.c:5:int main(void)
tests\tests2\67_macro_concat.c:6:int main(void)
tests\tests2\68_macro_param_list_err_1.c:4:int main(void)
tests\tests2\69_macro_param_list_err_2.c:4:int main(void)
tests\vla_test.c:75:int main(int argc, char **argv) {
win32\examples\fib.c:11:int main(int argc, char **argv)
win32\examples\hello_dll.c:3:// HELLO_DLL.C - Windows DLL example - main application part
win32\examples\hello_win.c:95: // the main window.
win32\examples\libtcc_test.c:35:int main(int argc, char **argv)
+++++++++++++++++++++++++++++++++++++++++++++++
***********************************************
For _tWinMain:
findstr /s /n /r /c:"winstart" *.c
-----------------------------------------------
tccpe.c:1764: : PE_GUI == pe_type ? "__winstart" : s1->unicode_mode ? "__wstart" :
"__start"
static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
{
..............................................
if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16")))
pe_type = PE_GUI;
else
if (find_elf_sym(symtab_section, PE_STDSYM("wWinMain","@16"))) {
pe_type = PE_GUI;
s1->unicode_mode = PE_GUI;
} else
..............................................
and
..............................................
unicode_mode = s1->unicode_mode;
start_symbol =
TCC_OUTPUT_MEMORY == s1->output_type
? PE_GUI == pe_type ? (unicode_mode ? "__wrunwinmain" : "__runwinmain")
: (unicode_mode ? "_wmain" : "_main")
: PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12")
: PE_GUI == pe_type ? (unicode_mode ? "__wwinstart": "__winstart")
: (unicode_mode ? "__wstart" : "__start")
;
..............................................
==>
tccelf.c
ST_FUNC int tcc_load_object_file(TCCState *s1,
int fd, unsigned long file_offset)
{
..............................................
/* add symbol */
name = (char *) strtab + sym->st_name;
#ifdef TCC_TARGET_PE
/* skip unused (undefined) */
int unicode_mode = s1->unicode_mode;
if ((unicode_mode == 3 /*PE_EXE*/ && strcmp(name, "main") != 0)
|| (unicode_mode == 2 /*PE_GUI*/
&& strcmp(name, PE_STDSYM("WinMain","@16")) != 0)
|| (unicode_mode == 0
&& strcmp(name, "wmain") != 0
&& strcmp(name, PE_STDSYM("wWinMain","@16")) != 0)
)
#endif
sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
sym->st_info, sym->st_other,
sym->st_shndx, name);
old_to_new_syms[i] = sym_index;
}
..............................................
-----------------------------------------------
win32\lib\wincrt1.c:12:int _winstart(void)
+++
-----------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
More:
1. unknown codes?
findstr /s /n il- *
-------------------
Changelog:206: 462: Use LGPL with bcheck.c and il-gen.c
il-gen.c:81:#include "il-opcodes.h"
il-gen.c:87:#include "il-opcodes.h"
2. Does unix/linux platform always use main as program's entry? And what about
"C67/coff" (TMS320C67xx target) environment?
ref:
http://en.wikipedia.org/wiki/TMS320C67xx#Software_support
http://en.wikipedia.org/wiki/DSP/BIOS
3. Some stub thing.
Useless functions are also added when linking the executable file.
If the size of crt1.c and wincrt1.c increases, the size of the compiled file
increases.
Maybe the Unicode and ASCII entry functions should be placed in seperate files,
for example: "crt1.c/crt1_w.c" and "wincrt1.c/wincrt1_w.c".
My tests confirmed it. TCC adds the whole codes in c a file or a file's o file,
as there is no optimization for the "defined but not used" codes.
So, shall we split the start_entry
(_winstart/_runwinmain and _wwinstart/_wrunwinmain)
for
PE_GUI/TCC_OUTPUT_MEMORY
into seperate files? Then, it can reduce the linked file size.
test_tmain.c
Description: Binary data
test_tWinMain.c
Description: Binary data
view_useless_code.c
Description: Binary data
_______________________________________________ Tinycc-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/tinycc-devel
