This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: multiple definitions of 'xxx keyed to...' in egcs-1.1.1
- To: law at cygnus dot com
- Subject: Re: multiple definitions of 'xxx keyed to...' in egcs-1.1.1
- From: hjl at lucon dot org (H.J. Lu)
- Date: Mon, 15 Feb 1999 17:00:31 -0800 (PST)
- Cc: martin at mira dot isdn dot cs dot tu-berlin dot de, egcs at egcs dot cygnus dot com
>
>
>
> 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 ());
}