[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Tinycc-devel] tcc 0.9.13 sometimes buggy with -shared -g
From: |
Basile STARYNKEVITCH |
Subject: |
[Tinycc-devel] tcc 0.9.13 sometimes buggy with -shared -g |
Date: |
Mon, 4 Nov 2002 00:37:45 +0100 |
Dear All,
[[Fabrice Bellard already knows about this bug since I sent hime a
private email in French]]
Sometimes, tcc generate a shared (non position independent) library
which cannot be dlopen-ed successfully.
I was not able to reproduce the bug with a tiny input. However, Here
is a 100+ line program which generates (dynamically) a file _gen.c then
compile it and tries to dlopen it. The generated file contains a
somehow random set of somehow random arithmetic functions.
This program uses the CC environment variable to compile the generated
_gen.c file into a _gen.so shared library. So changing the CC
environment variable just changes the invoked compiler (tcc by
default)
The "CC='tcc -g' ./testdlopen 100 40 9" command fails on dlopen
The "CC='tcc' ./testdlopen 100 40 9" command works
The "CC='gcc -g' ./testdlopen 100 40 9" also works.
In all 3 above cases the generated _gen.c file is exactly the
same (a 941 line file, of 22309 bytes). The only difference is the
compiler invoked.
The first argument (= 100 in above examples) of this testdlopen
program is the number of functions to generate. The second argument (=
40 in above examples) is the srand48 seed. The third argument (= 9
above) is the input parameter to the generated function.
I have the impression that there are some cases where tcc might
generate faulty ELF file (perhaps faulty symbol tables?). I even had a
case on a more complex program of mine. (and this actually may happen
even without -g even if the example here reproduces only the -g case).
If anyone have a clue on this bug please contribute.
If anyone succeeded to dlopen a tcc generated file of significant size
(eg >1000 lines), please tell us.
Since tcc is so fast, its possible use would be meta-programming:
generate code at run time and link it.
regards to all.
(my signature is after the testdlopen.c file)
################################################################
// file testdlopen.c
// emacs Time-stamp: <Nov 3 2002 21:40:30 Basile STARYNKEVITCH hector.lesours>
// prcs $ProjectHeader: Misc 0.2 Sun, 03 Nov 2002 21:40:49 +0100 basile $
// prcsid $Id: testdlopen.c 1.2 Sun, 03 Nov 2002 21:40:49 +0100 basile $
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <string.h>
char *cc;
const char *prefixes[] = {
"aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj", "kk", "ll",
"mm", "nn"
};
int
main (int argc, char **argv)
{
int nbf = 40;
FILE *f = 0;
int i = 0, j = 0, x = 0, y = 0;
char prevname[80];
char name[80];
char cmd[200];
void *dlh = 0;
void *ptr = 0;
int (*fun) ();
cc = getenv ("CC");
if (!cc)
cc = "tcc";
f = fopen ("_gen.c", "w");
if (!f)
{
perror ("_gen.c");
exit (1);
};
if (argc > 1)
nbf = atoi (argv[1]);
if (nbf < 2)
nbf = 2;
else if (nbf > 10000)
nbf = 10000;
if (argc > 2)
srand48 (atol (argv[2]));
if (argc > 3)
x = atoi (argv[3]);
printf (" nbf=%d x=%d\n", nbf, x);
memset (prevname, 0, sizeof (prevname));
memset (name, 0, sizeof (name));
for (i = 0; i < nbf; i++)
{
char *pref =
prefixes[(lrand48 ()) % (sizeof (prefixes) / sizeof (prefixes[0]))];
snprintf (name, sizeof (name) - 2, "%s_%d", pref, i);
fprintf (f, "int %s(int x) { int r=x;\n", name);
for (j = lrand48 () % 16 + 1; j > 0; j--)
{
switch (lrand48 () % 5)
{
case 0:
fprintf (f, " r= r %c %d;\n", "+-*/%|+-"[lrand48 () % 8],
lrand48 () % 100);
break;
case 1:
fprintf (f, " r += %d + x;\n", 1 + (lrand48 () % 10));
break;
case 2:
fprintf (f, " if (x>1) r = (r %c x) + %d;\n",
"+-*/%|+-"[lrand48 () % 8], lrand48 () % 100);
break;
case 3:
if (lrand48 () % 3 == 0 && prevname[0])
fprintf (f,
" while (r>=0 && r<x && r<500000000) r= r*10 +
(%s(r)&0xffff) + %d;\n",
prevname, 5 + (lrand48 () % 8));
else
fprintf (f, " while (r<x && r<10000000) r=(r*r)+%d;\n",
3 + (lrand48 () % 10));
break;
};
};
fprintf (f, " return r; } /*end %s*/\n\n", name);
strcpy (prevname, name);
};
fputs ("//eof\n", f);
fclose (f);
f = 0;
snprintf (cmd, sizeof(cmd), "%s -shared -o _gen.so _gen.c", cc);
printf ("before %s\n", cmd);
if (system (cmd) != 0)
{
fprintf (stderr, "command %s failed\n", cmd);
exit (1);
};
dlh = dlopen ("./_gen.so", RTLD_NOW);
if (!dlh)
{
fprintf (stderr, "dlopen _gen.so failed: %s\n", dlerror ());
exit (1);
};
printf ("after dlopen dlh=%p\n", dlh);
ptr = dlsym (dlh, name);
if (!ptr)
{
fprintf (stderr, "dlsym %s failed: %s\n", name, dlerror ());
exit (1);
};
printf ("dlsym found %s at %p with x=%d\n", name, ptr, x);
fun = ptr;
y = (*fun) (x);
printf ("result is y=%d\n", y);
return 0;
}
// eof $Id: testdlopen.c 1.2 Sun, 03 Nov 2002 21:40:49 +0100 basile $
################################################################
--
Basile STARYNKEVITCH http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net
alias: basile<at>tunes<dot>org
8, rue de la Faïencerie, 92340 Bourg La Reine, France
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Tinycc-devel] tcc 0.9.13 sometimes buggy with -shared -g,
Basile STARYNKEVITCH <=