This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: multiple definitions of 'xxx keyed to...' in egcs-1.1.1


> 
> 
> 
>   In message <m10Boh4-000392C@ocean.lucon.org>you write:
>   > It is a very hard problem. It may not have solutons for all platforms.
>   > But it doesn't mean we should not fix those we can fix.
> But it also doesn't mean we take the stance of fixing linux and ignoring
> everything else.
> 

Here is my proposal. main () in toplev.c calls unique_string () to
initialize a static variable in tree.c:

static char *file_function_name_base;

with

	file_function_name_base = unique_string ();

We also add a counter in tree.c:

static int file_function_name_counter;

get_file_function_name in tree.c will create a file funtcion name with

	file_function_name = file_function_name_base
			     + main_input_filename
			     + file_function_name_counter;

This way we can say with quite confidence that file_function_name will
be unique across all machines in the world for a given OS on a given
arch if they are configured properly. Of course, it may not work for
all OSes. But it should cover most if not all Unix-alike systems.

> Furthermore, this is an ABI/API change, we want to be very careful making
> such changes.
> 

I am not sure if the ABI/API change caused by making global ctors/dtors
static is visible to user. At least, it should be safe on ELF systems.


-- 
H.J. Lu (hjl@gnu.org)
---
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#if defined HAVE_SYS_UTSNAME_H && defined HAVE_UNAME
#include <sys/utsname.h>
#endif

#if defined HAVE_TIME_H && defined HAVE_STRFTIME \
    && defined HAVE_GMTIME && defined HAVE_TIME
#include <time.h>
#endif

#define xmalloc	malloc

#define is_valid_symbol_char(c) \
  ((c) == '_' || (c) == '.' || ((c) >= '0' && (c) <= '9') \
   || ((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))

char *
unique_string ()
{
  char *domainname = NULL;
  char *hostname = NULL;
  char *sysname = NULL;
  char *release = NULL;
  char *version = NULL;
  char *machine = NULL;
  char current_time [] = "yyyymmddhhmmss";
  long pid = getpid ();
  char *unique_name;
  int len;

#ifdef HAVE_GETDOMAINNAME
  {
    len = 0;
    do
      {
	len += 128;
	domainname = (char *) alloca (len);
	if (getdomainname (domainname, len) == 0)
	  break;
	else
	  domainname = NULL;
      }
    while (len < 512);
  }
#endif

#ifdef HAVE_GETHOSTNAME
  {
    len = 0;
    do
      {
	len += 128;
	hostname = (char *) alloca (len);
	if (gethostname (hostname, len) == 0)
	  break;
	else
	  hostname = NULL;
      }
    while (len < 512);
  }
#endif

#if defined HAVE_UNAME && defined HAVE_SYS_UTSNAME_H
  {
    struct utsname utsname;

    if (uname (&utsname) == 0)
      {
#ifdef HAVE_DOMAINNAME_IN_UTSNAME
        if (!domainname)
	  domainname = utsname.domainname;
#endif
#ifdef HAVE_NODENAME_IN_UTSNAME
        if (!hostname)
	  hostname = utsname.nodename;
#endif
#ifdef HAVE_SYSNAME_IN_UTSNAME
	sysname = utsname.sysname;
#endif
#ifdef HAVE_RELEASE_IN_UTSNAME
	release = utsname.release;
#endif
#ifdef HAVE_VERSION_IN_UTSNAME
	version = utsname.version;
#endif
#ifdef HAVE_MACHINE_IN_UTSNAME
	machine = utsname.machine;
#endif
      }
  }
#endif

  if (!domainname || *domainname == '\0')
    domainname = "localdomain";

  if (!hostname || *hostname == '\0')
    hostname = "localhost";

  if (!sysname || *sysname == '\0')
    sysname = "UnknownOS";

  if (!release || *release == '\0')
    release = "UnknownRelease";

  if (!version || *version == '\0')
    version = "UnknownVersion";

  if (!machine || *machine == '\0')
    machine = "UnknownMachine";

#if defined HAVE_STRFTIME && defined HAVE_GMTIME && defined HAVE_TIME
  {
    time_t t;
    
    t = time (NULL);
    if (strftime (current_time, sizeof (current_time),
    		  "%Y%m%d%H%M%S", gmtime (&t)) == 0)
      strcpy (current_time, "yyyymmddhhmmss");
  }
#endif

  {
    char *dot = strchr (hostname, '.');

    if (!dot || strchr (++dot, '.') == NULL)
      {
        /* There are no 2 dots in hostname. We need to append the
	   domainname. */
	len = 1 + strlen (hostname) + 1 + strlen (domainname)
	      + strlen (sysname) + strlen (release) + strlen (version)
	      + strlen (machine) + sizeof (current_time) + 8;

	unique_name = xmalloc (len);

        sprintf (unique_name, "_%s.%s%s%s%s%s%s%.8x",
		 hostname, domainname, sysname, release, version,
		 machine, current_time, pid);
      }
    else
      {
	len = 1 + strlen (hostname)
	      + strlen (sysname) + strlen (release) + strlen (version)
	      + strlen (machine) + sizeof (current_time) + 8;

	unique_name = xmalloc (len);

        sprintf (unique_name, "_%s%s%s%s%s%s%.8x",
		 hostname, sysname, release, version,
		 machine, current_time, pid);
      }
  }

  {
    int i;

    for (i = 1; i < len - 1 - sizeof (current_time) - 8; i++)
      {
        if (!is_valid_symbol_char (unique_name [i]))
	  unique_name [i] = '_';
      }
  }
  return unique_name;
}

main ()
{
  printf ("%s\n", unique_string ());
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]