tinycc-devel
[Top][All Lists]
Advanced

[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




reply via email to

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