Re: [Tinycc-devel] Re : Re: Re : Re: win32: -Wl,-nostdlib: undefined symbol 'memset'
Hello, On Tue, 12 Sep 2023, avih via Tinycc-devel wrote: > Also, what is "pure machine code"? With neither input nor output it > couldn't do anything but waste instruction cycles. A function implemented in machine code, where the input is the arguments in whatever calling convention the implementation uses, and the output is the return value and whatever memory side effects. I was hoping that compiling a C function which does not call other functions would result in machine code which does not call functions, except maybe existing internal compiler functions. In the example above it probably does not call external functions. But the user can't tell when it does and when it doesn't, which makes -nostdlib very problematic from a practical point of view. "Very problematic" seems an exaggeration given that e.g. GCC behaves exactly the same, given the right circumstances. TCC, as GCC, freely emits calls to memcpy, memmove and memset. It did so forever, like GCC. If anything then this is a problem of documentation (not for the command line help). TCCs docu is incomplete in many aspects, and this isn't the biggest problem by far. Even if these are terrible suggestions, the question remains: What does the user need to do in order to use -nostdlib? The user needs to provide a working implementation of memcpy, memmove, memset (and abort). And maybe also: what is -stdlib good for? Hmm? It's the opposite of nostdlib. And nostdlib is for exactly the documented purpose: prevent linking with default startup files and C library. If you're asking what _that_ is for, then: developing software that doesn't make use of the usual hosted C environment, like boot loaders or OS kernels. It's a special-case option, not to be used in random software development. Ciao, Michael. ___ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel
Re: [Tinycc-devel] Re : Re: Re : Re: win32: -Wl,-nostdlib: undefined symbol 'memset'
On Tuesday, September 12, 2023 at 12:44:45 PM GMT+3, grischka wrote: On 12.09.2023 11:01, avih via Tinycc-devel wrote: >> Tcc does not guarantee to compile pure C code into pure machine code, >> and any pure-C implementation which the user provides might end up >> depending on those functions involuntarily. The user has no control.. > How do you define "pure C code"? What I had in mind in this case was a C function which does not use asm and does not call other functions, like this: void *memset(void *str, int c, size_t n) { unsigned char *s = str; while (n--) *s++ = c; return str; } > And were did you get that that a compiler should be able to produce > runnable binaries from such "pure C" without calling into any library > functions? I did not say that. I was trying to explain the scope of the issue. > Also, what is "pure machine code"? With neither input nor output it > couldn't do anything but waste instruction cycles. A function implemented in machine code, where the input is the arguments in whatever calling convention the implementation uses, and the output is the return value and whatever memory side effects. I was hoping that compiling a C function which does not call other functions would result in machine code which does not call functions, except maybe existing internal compiler functions. In the example above it probably does not call external functions. But the user can't tell when it does and when it doesn't, which makes -nostdlib very problematic from a practical point of view. At this stage it's clear that external functions are expected, so the next step, if we want to have a usable -nostdlib, is to define the spec which a user has to follow in order to use it. My initial suggestion was to document the mem* and whatever other implementations which are required, possibly with a suggestion to link -ltcc1. But because the user can't tell if their "pure C" mem* implementations end up recursive or not, my second semi-suggestion was that maybe libtcc1 could provide such implementations which it can guarantee to not depend on external functions, and which the user may utilize if they don't intend to implement these functions in asm themselves. Even if these are terrible suggestions, the question remains: What does the user need to do in order to use -nostdlib? And maybe also: what is -stdlib good for? - avih ___ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel
Re: [Tinycc-devel] Re : Re: Re : Re: win32: -Wl,-nostdlib: undefined symbol 'memset'
On 12.09.2023 11:01, avih via Tinycc-devel wrote: Tcc does not guarantee to compile pure C code into pure machine code, and any pure-C implementation which the user provides might end up depending on those functions involuntarily. The user has no control.. How do you define "pure C code"? printf is pure (ANSI) C, no? And were did you get that that a compiler should be able to produce runnable binaries from such "pure C" without calling into any library functions? Also, what is "pure machine code"? With neither input nor output it couldn't do anything but waste instruction cycles. -- gr - avih ___ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel
Re: [Tinycc-devel] Re : Re: Re : Re: win32: -Wl,-nostdlib: undefined symbol 'memset'
On Tuesday, September 12, 2023 at 11:46:52 AM GMT+3, wrote: > If the 'memset' function you would provide also call 'memset' (aka itself) > then indeed it goes into full recursion (aka chicken-egg) and you should > reconsider your software architecture. It does not call memset (or memmove etc). It's written in pure C without calls, but tcc might insert a call to memmove when it compiles C code which does some assignment. E.g. uint64_t x, y = x; Might end up depending on memmove for the assignment. It doesn't in this case currently in x86, but how can I tell which assignments end up implemented by tcc using memmove, and which are not? That's the point of this additional issue. Tcc does not guarantee to compile pure C code into pure machine code, and any pure-C implementation which the user provides might end up depending on those functions involuntarily. The user has no control.. - avih - Mail d'origine - De: avih via Tinycc-devel À: tinycc-devel@nongnu.org Cc: avih Envoyé: Tue, 12 Sep 2023 10:33:01 +0200 (CEST) Objet: Re: [Tinycc-devel] Re : Re: win32: -Wl,-nostdlib: undefined symbol 'memset' And actually, there's another potential issue here: even if my suggestion was correct, how can I tell that the implementation of memset which I provide doesn't end up requiring memset? or that tomorrow it still won't require memset? Basically, tcc expects a stand alone implementation of memset which is fully self contained and does not depend on other functions, but when tcc inserts a dependency on such functions while compiling pure C code, I can't even compile such function in pure C in tcc with guaranteed no-dependencies. So it's a chicken and egg problem which might be hard to solve. Is asm required here? or maybe even that is not always enough? Maybe libtcc1 can provide implementations of _memset, _memmove etc which tcc knows does not depend those functions recursively, and can document that a user implementation of memset could call _memset etc when linking with libtcc1? On Tuesday, September 12, 2023 at 12:11:17 AM GMT+3, avih via Tinycc-devel wrote: Thanks. I was going by the official gcc docs. I did not test what it requires beyond those mem* implementations. Back to tcc, the current help for nostdlib is: > -nostdlib do not link with standard crt and libraries Would that be fair to change it to something like: > -nostdlib do not link with standard crt and libraries > may require memset, memmove, and linking with -ltcc1 That's apriori. Linking with libtcc1.a seems to address all the missing symbols in my example except memset and memmove. Are there others? like memcmp or memcpy which the gcc docs mention? or maybe even more beyond those? Should the mem* functions and libtcc1 cover these linking issues, assuming the user code doesn't use the crt and stdlib? - avih On Monday, September 11, 2023 at 10:32:26 PM GMT+3, grischka wrote: On 11.09.2023 14:41, avih via Tinycc-devel wrote: > But in the case of tcc, it's not documented, and seems to go > quite a bit further than what gcc requires libgcc.a from mingw-gcc-6.3.0 is 6218 kB, all full with according to your standards "undocumented" stuff that however gcc surely will require under certain circumstances and will miss when -nostdlib given. List follows: _chkstk.o ___chkstk _chkstk.o __alloca _chkstk_ms.o ___chkstk_ms _muldi3.o ___muldi3 _negdi2.o ___negdi2 _lshrdi3.o ___lshrdi3 _ashldi3.o ___ashldi3 _ashrdi3.o ___ashrdi3 _cmpdi2.o ___cmpdi2 _ucmpdi2.o ___ucmpdi2 _clear_cache.o ___clear_cache _trampoline.o _getpagesize _trampoline.o _mprotect __main.o ___do_global_dtors __main.o ___do_global_ctors __main.o ___main _absvsi2.o ___absvsi2 _absvdi2.o ___absvdi2 _addvsi3.o ___addvsi3 _addvdi3.o ___addvdi3 _subvsi3.o ___subvsi3 _subvdi3.o ___subvdi3 _mulvsi3.o ___mulvsi3 _mulvdi3.o ___mulvdi3 _negvsi2.o ___negvsi2 _negvdi2.o ___negvdi2 _ctors.o ___DTOR_LIST__ _ctors.o ___CTOR_LIST__ _ffssi2.o ___ffssi2 _ffsdi2.o ___ffsdi2 _clz.o ___clz_tab _clzsi2.o ___clzsi2 _clzdi2.o ___clzdi2 _ctzsi2.o ___ctzsi2 _ctzdi2.o ___ctzdi2 _popcount_tab.o ___popcount_tab _popcountsi2.o ___popcountsi2 _popcountdi2.o ___popcountdi2 _paritysi2.o ___paritysi2 _paritydi2.o ___paritydi2 _powisf2.o ___powisf2 _powidf2.o ___powidf2 _powixf2.o ___powixf2 _powitf2.o ___powitf2 _mulsc3.o ___mulsc3 _muldc3.o ___muldc3 _mulxc3.o ___mulxc3 _multc3.o ___multc3 _divsc3.o ___divsc3 _divdc3.o ___divdc3 _divxc3.o ___divxc3 _divtc3.o ___divtc3 _bswapsi2.o ___bswapsi2 _bswapdi2.o ___bswapdi2 _clrsbsi2.o ___clrsbsi2 _clrsbdi2.o ___clrsbdi2 _fixunssfsi.o ___fixunssfsi _fixunsdfsi.o ___fixunsdfsi _fixunsxfsi.o ___fixunsxfsi _fixsfdi.o ___fixsfdi _fixdfdi.o ___fixdfdi _fixxfdi.o ___fixxfdi _fixunssfdi.o ___fixunssfdi _fixunsdfdi.o ___fixunsdfdi _fixunsxfdi.o ___fixunsxfdi _floatdisf.o ___floatdisf _floatdidf.o ___floatdidf _floatdixf.o ___floatdixf _floatundisf.o ___floatundisf _floatundidf.o ___floatundidf _floatundixf.o ___floatundixf _eprintf.o ___eprintf __gcc_b
[Tinycc-devel] Re : Re: Re : Re: win32: -Wl,-nostdlib: undefined symbol 'memset'
If the 'memset' function you would provide also call 'memset' (aka itself) then indeed it goes into full recursion (aka chicken-egg) and you should reconsider your software architecture. When nostdlib is requested, it's more often than not that you are coding bare metal, doing your own operating system, hence providing your own memory manager and so. Hence 'memset' should be done in assembler, through inlining or so. Regards. - Mail d'origine - De: avih via Tinycc-devel À: tinycc-devel@nongnu.org Cc: avih Envoyé: Tue, 12 Sep 2023 10:33:01 +0200 (CEST) Objet: Re: [Tinycc-devel] Re : Re: win32: -Wl,-nostdlib: undefined symbol 'memset' And actually, there's another potential issue here: even if my suggestion was correct, how can I tell that the implementation of memset which I provide doesn't end up requiring memset? or that tomorrow it still won't require memset? Basically, tcc expects a stand alone implementation of memset which is fully self contained and does not depend on other functions, but when tcc inserts a dependency on such functions while compiling pure C code, I can't even compile such function in pure C in tcc with guaranteed no-dependencies. So it's a chicken and egg problem which might be hard to solve. Is asm required here? or maybe even that is not always enough? Maybe libtcc1 can provide implementations of _memset, _memmove etc which tcc knows does not depend those functions recursively, and can document that a user implementation of memset could call _memset etc when linking with libtcc1? On Tuesday, September 12, 2023 at 12:11:17 AM GMT+3, avih via Tinycc-devel wrote: Thanks. I was going by the official gcc docs. I did not test what it requires beyond those mem* implementations. Back to tcc, the current help for nostdlib is: > -nostdlib do not link with standard crt and libraries Would that be fair to change it to something like: > -nostdlib do not link with standard crt and libraries > may require memset, memmove, and linking with -ltcc1 That's apriori. Linking with libtcc1.a seems to address all the missing symbols in my example except memset and memmove. Are there others? like memcmp or memcpy which the gcc docs mention? or maybe even more beyond those? Should the mem* functions and libtcc1 cover these linking issues, assuming the user code doesn't use the crt and stdlib? - avih On Monday, September 11, 2023 at 10:32:26 PM GMT+3, grischka wrote: On 11.09.2023 14:41, avih via Tinycc-devel wrote: > But in the case of tcc, it's not documented, and seems to go > quite a bit further than what gcc requires libgcc.a from mingw-gcc-6.3.0 is 6218 kB, all full with according to your standards "undocumented" stuff that however gcc surely will require under certain circumstances and will miss when -nostdlib given. List follows: _chkstk.o ___chkstk _chkstk.o __alloca _chkstk_ms.o ___chkstk_ms _muldi3.o ___muldi3 _negdi2.o ___negdi2 _lshrdi3.o ___lshrdi3 _ashldi3.o ___ashldi3 _ashrdi3.o ___ashrdi3 _cmpdi2.o ___cmpdi2 _ucmpdi2.o ___ucmpdi2 _clear_cache.o ___clear_cache _trampoline.o _getpagesize _trampoline.o _mprotect __main.o ___do_global_dtors __main.o ___do_global_ctors __main.o ___main _absvsi2.o ___absvsi2 _absvdi2.o ___absvdi2 _addvsi3.o ___addvsi3 _addvdi3.o ___addvdi3 _subvsi3.o ___subvsi3 _subvdi3.o ___subvdi3 _mulvsi3.o ___mulvsi3 _mulvdi3.o ___mulvdi3 _negvsi2.o ___negvsi2 _negvdi2.o ___negvdi2 _ctors.o ___DTOR_LIST__ _ctors.o ___CTOR_LIST__ _ffssi2.o ___ffssi2 _ffsdi2.o ___ffsdi2 _clz.o ___clz_tab _clzsi2.o ___clzsi2 _clzdi2.o ___clzdi2 _ctzsi2.o ___ctzsi2 _ctzdi2.o ___ctzdi2 _popcount_tab.o ___popcount_tab _popcountsi2.o ___popcountsi2 _popcountdi2.o ___popcountdi2 _paritysi2.o ___paritysi2 _paritydi2.o ___paritydi2 _powisf2.o ___powisf2 _powidf2.o ___powidf2 _powixf2.o ___powixf2 _powitf2.o ___powitf2 _mulsc3.o ___mulsc3 _muldc3.o ___muldc3 _mulxc3.o ___mulxc3 _multc3.o ___multc3 _divsc3.o ___divsc3 _divdc3.o ___divdc3 _divxc3.o ___divxc3 _divtc3.o ___divtc3 _bswapsi2.o ___bswapsi2 _bswapdi2.o ___bswapdi2 _clrsbsi2.o ___clrsbsi2 _clrsbdi2.o ___clrsbdi2 _fixunssfsi.o ___fixunssfsi _fixunsdfsi.o ___fixunsdfsi _fixunsxfsi.o ___fixunsxfsi _fixsfdi.o ___fixsfdi _fixdfdi.o ___fixdfdi _fixxfdi.o ___fixxfdi _fixunssfdi.o ___fixunssfdi _fixunsdfdi.o ___fixunsdfdi _fixunsxfdi.o ___fixunsxfdi _floatdisf.o ___floatdisf _floatdidf.o ___floatdidf _floatdixf.o ___floatdixf _floatundisf.o ___floatundisf _floatundidf.o ___floatundidf _floatundixf.o ___floatundixf _eprintf.o ___eprintf __gcc_bcmp.o ___gcc_bcmp _divdi3.o ___divdi3 _moddi3.o ___moddi3 _udivdi3.o ___udivdi3 _umoddi3.o ___umoddi3 _udiv_w_sdiv.o ___udiv_w_sdiv _udivmoddi4.o ___udivmoddi4 bid_decimal_globals.o ___dfp_set_round bid_decimal_globals.o
[Tinycc-devel] Re : Re: Re : Re: win32: -Wl,-nostdlib: undefined symbol 'memset'
Thank, that's valuable information in one place. Regards. - Mail d'origine - De: grischka À: tinycc-devel@nongnu.org Envoyé: Mon, 11 Sep 2023 21:31:24 +0200 (CEST) Objet: Re: [Tinycc-devel] Re : Re: win32: -Wl,-nostdlib: undefined symbol 'memset' On 11.09.2023 14:41, avih via Tinycc-devel wrote: > But in the case of tcc, it's not documented, and seems to go > quite a bit further than what gcc requires libgcc.a from mingw-gcc-6.3.0 is 6218 kB, all full with according to your standards "undocumented" stuff that however gcc surely will require under certain circumstances and will miss when -nostdlib given. List follows: _chkstk.o___chkstk _chkstk.o__alloca _chkstk_ms.o___chkstk_ms _muldi3.o___muldi3 _negdi2.o___negdi2 _lshrdi3.o___lshrdi3 _ashldi3.o___ashldi3 _ashrdi3.o___ashrdi3 _cmpdi2.o___cmpdi2 _ucmpdi2.o___ucmpdi2 _clear_cache.o___clear_cache _trampoline.o_getpagesize _trampoline.o_mprotect __main.o___do_global_dtors __main.o___do_global_ctors __main.o___main _absvsi2.o___absvsi2 _absvdi2.o___absvdi2 _addvsi3.o___addvsi3 _addvdi3.o___addvdi3 _subvsi3.o___subvsi3 _subvdi3.o___subvdi3 _mulvsi3.o___mulvsi3 _mulvdi3.o___mulvdi3 _negvsi2.o___negvsi2 _negvdi2.o___negvdi2 _ctors.o___DTOR_LIST__ _ctors.o___CTOR_LIST__ _ffssi2.o___ffssi2 _ffsdi2.o___ffsdi2 _clz.o___clz_tab _clzsi2.o___clzsi2 _clzdi2.o___clzdi2 _ctzsi2.o___ctzsi2 _ctzdi2.o___ctzdi2 _popcount_tab.o___popcount_tab _popcountsi2.o___popcountsi2 _popcountdi2.o___popcountdi2 _paritysi2.o___paritysi2 _paritydi2.o___paritydi2 _powisf2.o___powisf2 _powidf2.o___powidf2 _powixf2.o___powixf2 _powitf2.o___powitf2 _mulsc3.o___mulsc3 _muldc3.o___muldc3 _mulxc3.o___mulxc3 _multc3.o___multc3 _divsc3.o___divsc3 _divdc3.o___divdc3 _divxc3.o___divxc3 _divtc3.o___divtc3 _bswapsi2.o___bswapsi2 _bswapdi2.o___bswapdi2 _clrsbsi2.o___clrsbsi2 _clrsbdi2.o___clrsbdi2 _fixunssfsi.o___fixunssfsi _fixunsdfsi.o___fixunsdfsi _fixunsxfsi.o___fixunsxfsi _fixsfdi.o___fixsfdi _fixdfdi.o___fixdfdi _fixxfdi.o___fixxfdi _fixunssfdi.o___fixunssfdi _fixunsdfdi.o___fixunsdfdi _fixunsxfdi.o___fixunsxfdi _floatdisf.o___floatdisf _floatdidf.o___floatdidf _floatdixf.o___floatdixf _floatundisf.o___floatundisf _floatundidf.o___floatundidf _floatundixf.o___floatundixf _eprintf.o___eprintf __gcc_bcmp.o___gcc_bcmp _divdi3.o___divdi3 _moddi3.o___moddi3 _udivdi3.o___udivdi3 _umoddi3.o___umoddi3 _udiv_w_sdiv.o___udiv_w_sdiv _udivmoddi4.o___udivmoddi4 bid_decimal_globals.o___dfp_set_round bid_decimal_globals.o___dfp_get_round bid_decimal_globals.o___dfp_clear_except bid_decimal_globals.o___dfp_test_except bid_decimal_globals.o___dfp_raise_except bid_decimal_globals.o___bid_IDEC_glbround bid_decimal_globals.o___bid_IDEC_glbflags bid_decimal_data.o___bid_power10_index_binexp_128 bid_decimal_data.o___bid_reciprocals10_64 bid_decimal_data.o___bid_short_recip_scale bid_decimal_data.o___bid_power10_index_binexp bid_decimal_data.o___bid_estimate_bin_expon bid_decimal_data.o___bid_power10_table_128 bid_decimal_data.o___bid_estimate_decimal_digits bid_decimal_data.o___bid_recip_scale bid_decimal_data.o___bid_reciprocals10_128 bid_decimal_data.o___bid_round_const_table_128 bid_decimal_data.o___bid_round_const_table bid_binarydecimal.o___bid32_to_binary32 bid_binarydecimal.o___bid64_to_binary32 bid_binarydecimal.o___bid128_to_binary32 bid_binarydecimal.o___bid32_to_binary64 bid_binarydecimal.o___bid64_to_binary64 bid_binarydecimal.o___bid128_to_binary64 bid_binarydecimal.o___bid32_to_binary80 bid_binarydecimal.o___bid64_to_binary80 bid_binarydecimal.o___bid128_to_binary80 bid_binarydecimal.o___bid32_to_binary128 bid_binarydecimal.o___bid64_to_binary128 bid_binarydecimal.o___bid128_to_binary128 bid_binarydecimal.o___binary32_to_bid32 bid_binarydecimal.o___binary64_to_bid32 bid_binarydecimal.o___binary80_to_bid32 bid_binarydecimal.o___binary128_to_bid32 bid_binarydecimal.o___binary32_to_bid64 bid_binarydecimal.o___binary64_to_bid64 bid_binarydecimal.o___binary80_to_bid64 bid_binarydecimal.o___binary128_to_bid64 bid_binarydecimal.o___binary32_to_bid128 bid_binarydecimal.o___binary64_to_bid128 bid_binarydecimal.o___binary80_to_bid128 bid_binarydecimal.o___binary128_to_bid128 bid_convert_data.o___bid_factors bid_convert_data.o___bid_packed_1_zeros bid_convert_data.o___bid_convert_table _isinfd32.o_isinfd32 _isinfd64.o_isinfd64 _isinfd128.o_isinfd128 bid64_noncomp.o___bid64_isSigned bid64_noncomp.o___bid64_isNormal bid64_noncomp.o___bid64_isSubnormal bid64_noncomp.o___bid64_isFinite bi