/* Collect static initialization info into data structures that can be
traversed by C++ initialization and finalization routines.
- Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Chris Smith (csmith@convex.com).
Heavily modified by Michael Meissner (meissner@cygnus.com),
Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
#include "config.h"
#include "system.h"
#include <signal.h>
+#if ! defined( SIGCHLD ) && defined( SIGCLD )
+# define SIGCHLD SIGCLD
+#endif
#ifdef vfork /* Autoconf may define this to fork for us. */
# define VFORK_STRING "fork"
lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
#endif /* VMS */
+#ifndef LIBRARY_PATH_ENV
+#define LIBRARY_PATH_ENV "LIBRARY_PATH"
+#endif
+
#define COLLECT
#include "collect2.h"
#include "demangle.h"
#include "obstack.h"
#include "intl.h"
+#include "version.h"
/* Obstack allocation and deallocation routines. */
#define obstack_chunk_alloc xmalloc
PASS_SECOND /* with constructors linked in */
};
-extern char *version_string;
-
int vflag; /* true if -v */
static int rflag; /* true if -r */
static int strip_flag; /* true if -s */
static const char *o_file; /* <xxx>.o for constructor/destructor list. */
#ifdef COLLECT_EXPORT_LIST
static const char *export_file; /* <xxx>.x for AIX export list. */
-static const char *import_file; /* <xxx>.p for AIX import list. */
#endif
const char *ldout; /* File for ld errors. */
static const char *output_file; /* Output file for ld. */
static struct head destructors; /* list of destructors found */
#ifdef COLLECT_EXPORT_LIST
static struct head exports; /* list of exported symbols */
-static struct head imports; /* list of imported symbols */
-static struct head undefined; /* list of undefined symbols */
#endif
static struct head frame_tables; /* list of frame unwind info tables */
static const char *libexts[3] = {"a", "so", NULL}; /* possible library extentions */
#endif
-static void handler PROTO((int));
-static int is_ctor_dtor PROTO((const char *));
-static char *find_a_file PROTO((struct path_prefix *, const char *));
-static void add_prefix PROTO((struct path_prefix *, const char *));
-static void prefix_from_env PROTO((const char *, struct path_prefix *));
-static void prefix_from_string PROTO((const char *, struct path_prefix *));
-static void do_wait PROTO((const char *));
-static void fork_execute PROTO((const char *, char **));
-static void maybe_unlink PROTO((const char *));
-static void add_to_list PROTO((struct head *, const char *));
-static int extract_init_priority PROTO((const char *));
-static void sort_ids PROTO((struct head *));
-static void write_list PROTO((FILE *, const char *, struct id *));
+static void handler PARAMS ((int));
+static int is_ctor_dtor PARAMS ((const char *));
+static char *find_a_file PARAMS ((struct path_prefix *, const char *));
+static void add_prefix PARAMS ((struct path_prefix *, const char *));
+static void prefix_from_env PARAMS ((const char *, struct path_prefix *));
+static void prefix_from_string PARAMS ((const char *, struct path_prefix *));
+static void do_wait PARAMS ((const char *));
+static void fork_execute PARAMS ((const char *, char **));
+static void maybe_unlink PARAMS ((const char *));
+static void add_to_list PARAMS ((struct head *, const char *));
+static int extract_init_priority PARAMS ((const char *));
+static void sort_ids PARAMS ((struct head *));
+static void write_list PARAMS ((FILE *, const char *, struct id *));
#ifdef COLLECT_EXPORT_LIST
-static void dump_list PROTO((FILE *, const char *, struct id *));
+static void dump_list PARAMS ((FILE *, const char *, struct id *));
#endif
#if 0
-static void dump_prefix_list PROTO((FILE *, const char *, struct prefix_list *));
+static void dump_prefix_list PARAMS ((FILE *, const char *, struct prefix_list *));
#endif
-static void write_list_with_asm PROTO((FILE *, const char *, struct id *));
-static void write_c_file PROTO((FILE *, const char *));
-static void write_c_file_stat PROTO((FILE *, const char *));
+static void write_list_with_asm PARAMS ((FILE *, const char *, struct id *));
+static void write_c_file PARAMS ((FILE *, const char *));
+static void write_c_file_stat PARAMS ((FILE *, const char *));
#ifndef LD_INIT_SWITCH
-static void write_c_file_glob PROTO((FILE *, const char *));
+static void write_c_file_glob PARAMS ((FILE *, const char *));
#endif
-static void scan_prog_file PROTO((const char *, enum pass));
+static void scan_prog_file PARAMS ((const char *, enum pass));
#ifdef SCAN_LIBRARIES
-static void scan_libraries PROTO((const char *));
+static void scan_libraries PARAMS ((const char *));
+#endif
+#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
+static int is_in_args PARAMS ((const char *, const char **, const char **));
#endif
#ifdef COLLECT_EXPORT_LIST
-static int is_in_list PROTO((const char *, struct id *));
-static void write_aix_file PROTO((FILE *, struct id *));
-static char *resolve_lib_name PROTO((const char *));
-static int use_import_list PROTO((const char *));
-static int ignore_library PROTO((const char *));
+static int is_in_list PARAMS ((const char *, struct id *));
+static void write_aix_file PARAMS ((FILE *, struct id *));
+static char *resolve_lib_name PARAMS ((const char *));
+static int ignore_library PARAMS ((const char *));
#endif
-static char *extract_string PROTO((const char **));
+static char *extract_string PARAMS ((const char **));
\f
#ifdef NO_DUP2
int
#ifdef COLLECT_EXPORT_LIST
if (export_file != 0 && export_file[0])
maybe_unlink (export_file);
-
- if (import_file != 0 && import_file[0])
- maybe_unlink (import_file);
#endif
if (ldout != 0 && ldout[0])
\f
/* Notify user of a non-error. */
void
-notice VPROTO((const char *msgid, ...))
+notice VPARAMS ((const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
const char *msgid;
/* Die when sys call fails. */
void
-fatal_perror VPROTO((const char * msgid, ...))
+fatal_perror VPARAMS ((const char * msgid, ...))
{
#ifndef ANSI_PROTOTYPES
const char *msgid;
/* Just die. */
void
-fatal VPROTO((const char * msgid, ...))
+fatal VPARAMS ((const char * msgid, ...))
{
#ifndef ANSI_PROTOTYPES
const char *msgid;
/* Write error message. */
void
-error VPROTO((const char * msgid, ...))
+error VPARAMS ((const char * msgid, ...))
{
#ifndef ANSI_PROTOTYPES
const char * msgid;
#ifdef COLLECT_EXPORT_LIST
if (export_file != 0 && export_file[0])
maybe_unlink (export_file);
-
- if (import_file != 0 && import_file[0])
- maybe_unlink (import_file);
#endif
signal (signo, SIG_DFL);
fclose (stream);
}
\f
-/* Decide whether the given symbol is:
- a constructor (1), a destructor (2), or neither (0). */
+/* Decide whether the given symbol is: a constructor (1), a destructor
+ (2), a routine in a shared object that calls all the constructors
+ (3) or destructors (4), a DWARF exception-handling table (5), or
+ nothing special (0). */
static int
is_ctor_dtor (s)
register const char *orig_s = s;
static struct names special[] = {
-#ifdef NO_DOLLAR_IN_LABEL
-#ifdef NO_DOT_IN_LABEL
{ "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
{ "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
{ "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
-#else
- { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
- { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
- { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },
-#endif
-#else
- { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
- { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
- { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },
-#endif
{ "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
{ "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
#ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
return 0;
}
\f
-/* By default, colon separates directories in a path. */
-#ifndef PATH_SEPARATOR
-#define PATH_SEPARATOR ':'
-#endif
-
/* We maintain two prefix lists: one from COMPILER_PATH environment variable
and one from the PATH variable. */
if (debug)
fprintf (stderr, "Looking for '%s'\n", name);
-#ifdef EXECUTABLE_SUFFIX
- len += strlen (EXECUTABLE_SUFFIX);
+#ifdef HOST_EXECUTABLE_SUFFIX
+ len += strlen (HOST_EXECUTABLE_SUFFIX);
#endif
temp = xmalloc (len);
return temp;
}
-#ifdef EXECUTABLE_SUFFIX
+#ifdef HOST_EXECUTABLE_SUFFIX
/* Some systems have a suffix for executable files.
So try appending that. */
strcpy (temp, name);
- strcat (temp, EXECUTABLE_SUFFIX);
+ strcat (temp, HOST_EXECUTABLE_SUFFIX);
if (access (temp, X_OK) == 0)
return temp;
&& access (temp, X_OK) == 0)
return temp;
-#ifdef EXECUTABLE_SUFFIX
+#ifdef HOST_EXECUTABLE_SUFFIX
/* Some systems have a suffix for executable files.
So try appending that. */
- strcat (temp, EXECUTABLE_SUFFIX);
+ strcat (temp, HOST_EXECUTABLE_SUFFIX);
if (stat (temp, &st) >= 0
&& ! S_ISDIR (st.st_mode)
{
strcpy (nstore, "./");
}
- else if (endp[-1] != '/')
+ else if (! IS_DIR_SEPARATOR (endp[-1]))
{
- nstore[endp-startp] = '/';
+ nstore[endp-startp] = DIR_SEPARATOR;
nstore[endp-startp+1] = 0;
}
else
\f
/* Main program. */
-int main PROTO ((int, char *[]));
+int main PARAMS ((int, char *[]));
int
main (argc, argv)
int argc;
FILE *outf;
#ifdef COLLECT_EXPORT_LIST
FILE *exportf;
- FILE *importf;
#endif
const char *ld_file_name;
const char *p;
int num_c_args = argc+9;
#if defined (COLLECT2_HOST_INITIALIZATION)
- /* Perform system dependant initialization, if neccessary. */
+ /* Perform system dependent initialization, if neccessary. */
COLLECT2_HOST_INITIALIZATION;
#endif
+#ifdef SIGCHLD
+ /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
+ receive the signal. A different setting is inheritable */
+ signal (SIGCHLD, SIG_DFL);
+#endif
+
+/* LC_CTYPE determines the character set used by the terminal so it has be set
+ to output messages correctly. */
+
#ifdef HAVE_LC_MESSAGES
+ setlocale (LC_CTYPE, "");
setlocale (LC_MESSAGES, "");
+#else
+ setlocale (LC_ALL, "");
#endif
+
(void) bindtextdomain (PACKAGE, localedir);
(void) textdomain (PACKAGE);
set first, in case a diagnostic is issued. */
ld1 = (const char **)(ld1_argv = (char **) xcalloc(sizeof (char *), argc+3));
- ld2 = (const char **)(ld2_argv = (char **) xcalloc(sizeof (char *), argc+6));
+ ld2 = (const char **)(ld2_argv = (char **) xcalloc(sizeof (char *), argc+10));
object = (const char **)(object_lst = (char **) xcalloc(sizeof (char *), argc));
#ifdef DEBUG
obstack_begin (&permanent_obstack, 0);
temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
- current_demangling_style = gnu_demangling;
+ current_demangling_style = auto_demangling;
p = getenv ("COLLECT_GCC_OPTIONS");
while (p && *p)
{
num_c_args++;
}
obstack_free (&temporary_obstack, temporary_firstobj);
- ++num_c_args;
+
+ /* -fno-exceptions -w */
+ num_c_args += 2;
c_ptr = (const char **)
(c_argv = (char **) xcalloc (sizeof (char *), num_c_args));
o_file = make_temp_file (".o");
#ifdef COLLECT_EXPORT_LIST
export_file = make_temp_file (".x");
- import_file = make_temp_file (".p");
#endif
ldout = make_temp_file (".ld");
*c_ptr++ = c_file_name;
*c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0)
shared_obj = 1;
+ if (*q == '-' && q[1] == 'B')
+ {
+ *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
+ if (q[2] == 0)
+ {
+ q = extract_string (&p);
+ *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
+ }
+ }
}
obstack_free (&temporary_obstack, temporary_firstobj);
*c_ptr++ = "-fno-exceptions";
+ *c_ptr++ = "-w";
/* !!! When GCC calls collect2,
it does not know whether it is calling collect2 or ld.
/* Resolving full library name. */
const char *s = resolve_lib_name (arg+2);
- /* If we will use an import list for this library,
- we should exclude it from ld args. */
- if (use_import_list (s))
- {
- ld1--;
- ld2--;
- }
-
/* Saving a full library name. */
add_to_list (&libs, s);
}
case 'L':
add_prefix (&cmdline_lib_dirs, arg+2);
break;
+#else
+#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
+ case 'L':
+ if (is_in_args (arg, (const char **) ld1_argv, ld1-1))
+ --ld1;
+ break;
+#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
#endif
case 'o':
if (arg[2] == '\0')
output_file = *ld1++ = *ld2++ = *++argv;
- else
+ else if (1
+#ifdef SWITCHES_NEED_SPACES
+ && ! strchr (SWITCHES_NEED_SPACES, arg[1])
+#endif
+ )
+
output_file = &arg[2];
break;
break;
}
}
- else if ((p = rindex (arg, '.')) != (char *) 0
+ else if ((p = strrchr (arg, '.')) != (char *) 0
&& (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
- || strcmp (p, ".so") == 0))
+ || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
+ || strcmp (p, ".obj") == 0))
{
if (first_file)
{
*ld2++ = arg;
}
}
- if (p[1] == 'o')
+ if (p[1] == 'o' || p[1] == 'l')
*object++ = arg;
#ifdef COLLECT_EXPORT_LIST
/* libraries can be specified directly, i.e. without -l flag. */
else
{
- /* If we will use an import list for this library,
- we should exclude it from ld args. */
- if (use_import_list (arg))
- {
- ld1--;
- ld2--;
- }
-
/* Saving a full library name. */
add_to_list (&libs, arg);
}
/* The AIX linker will discard static constructors in object files if
nothing else in the file is referenced, so look at them first. */
{
- char **export_object_lst = object_lst;
+ const char **export_object_lst = (const char **)object_lst;
while (export_object_lst < object)
scan_prog_file (*export_object_lst++, PASS_OBJ);
if (exports.first)
{
- char *buf = xmalloc (strlen (export_file) + 5);
-
- sprintf (buf, "-bE:%s", export_file);
+ char *buf = concat ("-bE:", export_file, NULL);
+
*ld1++ = buf;
*ld2++ = buf;
if (fclose (exportf))
fatal_perror ("fclose %s", export_file);
}
-
- if (imports.first)
- {
- char *buf = xmalloc (strlen (import_file) + 5);
-
- sprintf (buf, "-bI:%s", import_file);
- *ld1++ = buf;
- *ld2++ = buf;
-
- importf = fopen (import_file, "w");
- if (importf == (FILE *) 0)
- fatal_perror ("%s", import_file);
- fputs ("#! .\n", importf);
- write_aix_file (importf, imports.first);
- if (fclose (importf))
- fatal_perror ("fclose %s", import_file);
- }
#endif
*c_ptr++ = c_file;
if (ptr)
fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
- ptr = getenv ("LIBRARY_PATH");
+ ptr = getenv (LIBRARY_PATH_ENV);
if (ptr)
- fprintf (stderr, "LIBRARY_PATH = %s\n", ptr);
+ fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr);
fprintf (stderr, "\n");
}
/* But make sure we delete the export file we may have created. */
if (export_file != 0 && export_file[0])
maybe_unlink (export_file);
- if (import_file != 0 && import_file[0])
- maybe_unlink (import_file);
#endif
maybe_unlink (c_file);
maybe_unlink (o_file);
#ifdef COLLECT_EXPORT_LIST
maybe_unlink (export_file);
- maybe_unlink (import_file);
#endif
maybe_unlink (c_file);
maybe_unlink (o_file);
/* Tell the linker that we have initializer and finalizer functions. */
#ifdef LD_INIT_SWITCH
+#ifdef COLLECT_EXPORT_LIST
+ *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL);
+#else
*ld2++ = LD_INIT_SWITCH;
*ld2++ = initname;
*ld2++ = LD_FINI_SWITCH;
*ld2++ = fininame;
#endif
+#endif
#ifdef COLLECT_EXPORT_LIST
if (shared_obj)
/* If we did not add export flag to link arguments before, add it to
second link phase now. No new exports should have been added. */
if (! exports.first)
- {
- char *buf = xmalloc (strlen (export_file) + 5);
-
- sprintf (buf, "-bE:%s", export_file);
- *ld2++ = buf;
- }
+ *ld2++ = concat ("-bE:", export_file, NULL);
add_to_list (&exports, initname);
add_to_list (&exports, fininame);
#ifdef COLLECT_EXPORT_LIST
maybe_unlink (export_file);
- maybe_unlink (import_file);
#endif
return 0;
if (WIFSIGNALED (status))
{
int sig = WTERMSIG (status);
- error ((status & 0200
- ? "%s terminated with signal %d [%s]"
- : "%s terminated with signal %d [%s], core dumped"),
- prog,
- sig,
- strsignal(sig));
+ error ("%s terminated with signal %d [%s]%s",
+ prog, sig, strsignal(sig),
+ status & 0200 ? "" : ", core dumped");
collect_exit (FATAL_EXIT_CODE);
}
}
}
+#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
+/* Given a STRING, return nonzero if it occurs in the list in range
+ [ARGS_BEGIN,ARGS_END). */
+
+static int
+is_in_args (string, args_begin, args_end)
+ const char *string;
+ const char **args_begin;
+ const char **args_end;
+{
+ const char **args_pointer;
+ for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer)
+ if (strcmp (string, *args_pointer) == 0)
+ return 1;
+ return 0;
+}
+#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
+
#ifdef COLLECT_EXPORT_LIST
/* This function is really used only on AIX, but may be useful. */
static int
int frames = (frame_tables.number > 0);
/* Figure out name of output_file, stripping off .so version. */
- p = rindex (output_file, '/');
+ p = strrchr (output_file, '/');
if (p == 0)
p = output_file;
else
q = p;
while (q)
{
- q = index (q,'.');
+ q = strchr (q,'.');
if (q == 0)
{
q = p + strlen (p);
notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
output_file, prefix);
-#define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
- initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
- sprintf (initname, INIT_NAME_FORMAT, prefix);
-
-#define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
- fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
- sprintf (fininame, FINI_NAME_FORMAT, prefix);
+ initname = concat ("_GLOBAL__FI_", prefix, NULL);
+ fininame = concat ("_GLOBAL__FD_", prefix, NULL);
free (prefix);
const char *prog_name;
enum pass which_pass;
{
- void (*int_handler) PROTO ((int));
- void (*quit_handler) PROTO ((int));
+ void (*int_handler) PARAMS ((int));
+ void (*quit_handler) PARAMS ((int));
char *real_nm_argv[4];
const char **nm_argv = (const char **) real_nm_argv;
int pid;
}
/* Parent context from here on. */
- int_handler = (void (*) PROTO ((int))) signal (SIGINT, SIG_IGN);
+ int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
#ifdef SIGQUIT
- quit_handler = (void (*) PROTO ((int))) signal (SIGQUIT, SIG_IGN);
+ quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN);
#endif
if (close (pipe_fd[1]) < 0)
/* Map the file indicated by NAME into memory and store its address. */
-static void mapfile PROTO ((const char *));
+static void mapfile PARAMS ((const char *));
static void
mapfile (name)
static const char *libname;
-static int libselect PROTO ((struct direct *));
+static int libselect PARAMS ((struct direct *));
static int
libselect (d)
We must verify that the extension is numeric, because Sun saves the
original versions of patched libraries with a .FCS extension. Files with
invalid extensions must go last in the sort, so that they will not be used. */
-static int libcompare PROTO ((struct direct **, struct direct **));
+static int libcompare PARAMS ((struct direct **, struct direct **));
static int
libcompare (d1, d2)
/* Given the name NAME of a dynamic dependency, find its pathname and add
it to the list of libraries. */
-static void locatelib PROTO ((const char *));
+static void locatelib PARAMS ((const char *));
static void
locatelib (name)
{
static struct head libraries; /* list of shared libraries found */
struct id *list;
- void (*int_handler) PROTO ((int));
- void (*quit_handler) PROTO ((int));
+ void (*int_handler) PARAMS ((int));
+ void (*quit_handler) PARAMS ((int));
char *real_ldd_argv[4];
const char **ldd_argv = (const char **) real_ldd_argv;
int pid;
}
/* Parent context from here on. */
- int_handler = (void (*) PROTO ((int))) signal (SIGINT, SIG_IGN);
+ int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
#ifdef SIGQUIT
- quit_handler = (void (*) PROTO ((int))) signal (SIGQUIT, SIG_IGN);
+ quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN);
#endif
if (close (pipe_fd[1]) < 0)
/* Read each line of ldd output. */
while (fgets (buf, sizeof buf, inf) != (char *) 0)
{
- int ch, ch2;
+ int ch2;
char *name, *end, *p = buf;
/* Extract names of libraries and add to list. */
#ifdef OBJECT_FORMAT_COFF
#if defined(EXTENDED_COFF)
+
# define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
# define GCC_SYMENT SYMR
# define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
# define GCC_SYMINC(X) (1)
# define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
# define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
+
#else
+
# define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
# define GCC_SYMENT SYMENT
# define GCC_OK_SYMBOL(X) \
(((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
# define GCC_SYMINC(X) ((X).n_numaux+1)
# define GCC_SYMZERO(X) 0
+
+/* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
+#ifdef _AIX51
+# define GCC_CHECK_HDR(X) \
+ ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
+ || (HEADER (X).f_magic == 0767 && aix64_flag))
+#else
# define GCC_CHECK_HDR(X) \
((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
|| (HEADER (X).f_magic == 0757 && aix64_flag))
#endif
+#endif
+
extern char *ldgetname ();
/* COFF version to scan the name list of the loaded program for
LDFILE *ldptr = NULL;
int sym_index, sym_count;
int is_shared = 0;
-#ifdef COLLECT_EXPORT_LIST
- /* Should we generate an import list for given prog_name? */
- int import_flag = (which_pass == PASS_OBJ ? 0 : use_import_list (prog_name));
-#endif
if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
return;
switch (is_ctor_dtor (name))
{
case 1:
- if (! is_shared) add_to_list (&constructors, name);
+ if (! is_shared)
+ add_to_list (&constructors, name);
#ifdef COLLECT_EXPORT_LIST
if (which_pass == PASS_OBJ)
add_to_list (&exports, name);
- /* If this symbol was undefined and we are building
- an import list, we should add a symbol to this
- list. */
- else
- if (import_flag
- && is_in_list (name, undefined.first))
- add_to_list (&imports, name);
#endif
break;
case 2:
- if (! is_shared) add_to_list (&destructors, name);
+ if (! is_shared)
+ add_to_list (&destructors, name);
#ifdef COLLECT_EXPORT_LIST
if (which_pass == PASS_OBJ)
add_to_list (&exports, name);
- /* If this symbol was undefined and we are building
- an import list, we should add a symbol to this
- list. */
- else
- if (import_flag
- && is_in_list (name, undefined.first))
- add_to_list (&imports, name);
#endif
break;
#ifdef COLLECT_EXPORT_LIST
case 3:
+#ifndef LD_INIT_SWITCH
if (is_shared)
add_to_list (&constructors, name);
+#endif
break;
case 4:
+#ifndef LD_INIT_SWITCH
if (is_shared)
add_to_list (&destructors, name);
+#endif
break;
#endif
case 5:
if (! is_shared)
add_to_list (&frame_tables, name);
+#ifdef COLLECT_EXPORT_LIST
+ if (which_pass == PASS_OBJ)
+ add_to_list (&exports, name);
+#endif
break;
default: /* not a constructor or destructor */
#ifdef COLLECT_EXPORT_LIST
/* If we are building a shared object on AIX we need
- to explicitly export all global symbols or add
- them to import list. */
+ to explicitly export all global symbols. */
if (shared_obj)
{
if (which_pass == PASS_OBJ && (! export_flag))
add_to_list (&exports, name);
- else if (! is_shared && which_pass == PASS_FIRST
- && import_flag
- && is_in_list(name, undefined.first))
- add_to_list (&imports, name);
}
#endif
continue;
}
-#if !defined(EXTENDED_COFF)
if (debug)
+#if !defined(EXTENDED_COFF)
fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
symbol.n_scnum, symbol.n_sclass,
(symbol.n_type ? "0" : ""), symbol.n_type,
name);
#else
- if (debug)
fprintf (stderr,
"\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
symbol.iss, (long) symbol.value, symbol.index, name);
#endif
}
-#ifdef COLLECT_EXPORT_LIST
- /* If we are building a shared object we should collect
- information about undefined symbols for later
- import list generation. */
- else if (shared_obj && GCC_UNDEF_SYMBOL (symbol))
- {
- char *name;
-
- if ((name = ldgetname (ldptr, &symbol)) == NULL)
- continue; /* should never happen */
-
- /* All AIX function names have a duplicate entry
- beginning with a dot. */
- if (*name == '.')
- ++name;
- add_to_list (&undefined, name);
- }
-#endif
}
}
#ifdef COLLECT_EXPORT_LIST
#ifdef COLLECT_EXPORT_LIST
-
-/* This new function is used to decide whether we should
- generate import list for an object or to use it directly. */
-static int
-use_import_list (prog_name)
- const char *prog_name;
-{
- char *p;
-
- /* If we do not build a shared object then import list should not be used. */
- if (! shared_obj) return 0;
-
- /* Currently we check only for libgcc, but this can be changed in future. */
- p = strstr (prog_name, "libgcc.a");
- if (p != 0 && (strlen (p) == sizeof ("libgcc.a") - 1))
- return 1;
- return 0;
-}
-
/* Given a library name without "lib" prefix, this function
returns a full library name including a path. */
static char *
struct prefix_list *list = libpaths[i]->plist;
for (; list; list = list->next)
{
+ /* The following lines are needed because path_prefix list
+ may contain directories both with trailing '/' and
+ without it. */
+ const char *p = "";
+ if (list->prefix[strlen(list->prefix)-1] != '/')
+ p = "/";
for (j = 0; libexts[j]; j++)
{
- /* The following lines are needed because path_prefix list
- may contain directories both with trailing '/' and
- without it. */
- const char *p = "";
- if (list->prefix[strlen(list->prefix)-1] != '/')
- p = "/";
sprintf (lib_buf, "%s%slib%s.%s",
list->prefix, p, name, libexts[j]);
if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
static const char *aix_std_libs[] = {
"/unix",
"/lib/libc.a",
+ "/lib/libm.a",
"/lib/libc_r.a",
+ "/lib/libm_r.a",
"/usr/lib/libc.a",
+ "/usr/lib/libm.a",
"/usr/lib/libc_r.a",
+ "/usr/lib/libm_r.a",
"/usr/lib/threads/libc.a",
"/usr/ccs/lib/libc.a",
+ "/usr/ccs/lib/libm.a",
"/usr/ccs/lib/libc_r.a",
+ "/usr/ccs/lib/libm_r.a",
NULL
};
if (! strcmp (name, *p)) return 1;
return 0;
}
-
#endif
#endif /* OBJECT_FORMAT_COFF */
extern int decode_mach_o_hdr ();
extern int encode_mach_o_hdr ();
-static void add_func_table PROTO((mo_header_t *, load_all_t *,
+static void add_func_table PARAMS ((mo_header_t *, load_all_t *,
symbol_info_t *, int));
-static void print_header PROTO((mo_header_t *));
-static void print_load_command PROTO((load_union_t *, size_t, int));
-static void bad_header PROTO((int));
-static struct file_info *read_file PROTO((const char *, int, int));
-static void end_file PROTO((struct file_info *));
+static void print_header PARAMS ((mo_header_t *));
+static void print_load_command PARAMS ((load_union_t *, size_t, int));
+static void bad_header PARAMS ((int));
+static struct file_info *read_file PARAMS ((const char *, int, int));
+static void end_file PARAMS ((struct file_info *));
\f
/* OSF/rose specific version to scan the name list of the loaded
program for the symbols g++ uses for static constructors and
if (rw)
{
load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
- bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size);
+ memcpy ((char *)ptr, (char *)load_hdr, load_hdr->hdr.ldci_cmd_size);
load_hdr = ptr;
/* null out old command map, because we will rewrite at the end. */