tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] Re : Re: win32: -Wl,-nostdlib: undefined symbol 'mem


From: avih
Subject: Re: [Tinycc-devel] Re : Re: win32: -Wl,-nostdlib: undefined symbol 'memset'
Date: Mon, 11 Sep 2023 12:41:34 +0000 (UTC)

The issue is bigger than just memset. I found at least 5 more functions
which are required in some cases, not all of them part of stdlib, and I'm
guessing sure there are more, depending on the platform. For instance:

// test3.c ---------------

typedef struct { int a, b; } S;

void _start(void) {
S x = {0}; // requires memset with i386, x86-64
int z[x.a]; // requires alloca with i386, x86-64 (on win32, not linux)
S y = x; // requires memmove with i386

long long llng;
llng /= 2; // requires __divdi3 with i386
llng %= 2; // requires __moddi3 with i386
*z *= 1.0; // requires __fixdfdi with i386
}

// ---------------

Then compile using:
tcc -Wl,-nostdlib test3.c

Result on windows, as i386:
tcc: error: undefined symbol 'memset'
tcc: error: undefined symbol 'alloca'
tcc: error: undefined symbol 'memmove'
tcc: error: undefined symbol '__divdi3'
tcc: error: undefined symbol '__moddi3'
tcc: error: undefined symbol '__fixdfdi'


So even if memset and memmove can be provided by the user, others
are not standard and undocumented (__divdi3 does not appear in C99),
while some might not even be possible - how can the user provide an
alloca implementation which allocates on the stack which tcc manages?

Looking at the gcc docs, it includes this about -nostdlib:

> The compiler may generate calls to "memcmp", "memset", "memcpy"
> and "memmove". These entries are usually resolved by entries in
> libc. These entry points should be supplied through some other
> mechanism when this option is specified.

So even if not very friendly (because this is the very thing
which the compiler is supposed to compiled into machine code...),
at least it's well defined what the user should provide in such case.

But in the case of tcc, it's not documented, and seems to go
quite a bit further than what gcc requires, to the point which
makes this option completely impractical for tcc end users.

- avih

On Sunday, September 10, 2023 at 01:51:14 PM GMT+3, Ziyao via Tinycc-devel <tinycc-devel@nongnu.org> wrote:


On 2023-09-10 15:13, Страхиња Радић wrote:

> What is weird is that tcc requires a libc function, memset, when none
> is
> explicitly requested, when for example this code:

It is not that weird I think. Early versions of GCC generates a call to
memset()
as well when zeroing a block of memory [1]

btw, the call could be easily eliminated by add a function like
gen_struct_copy()
in x86_64-gen.c. And this call may lead to problems. For example, the
dynamic
linker of musl has code that zeros a structure, but at that time
memset() has not
been relocated, result in a segfault.

--
Ziyao

[1]: check for clear_storage() in gcc/expr.c of commit 3b6f75e2 of gcc


_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

reply via email to

[Prev in Thread] Current Thread [Next in Thread]