summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/collect2.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>1999-08-26 09:30:50 +0000
committerobrien <obrien@FreeBSD.org>1999-08-26 09:30:50 +0000
commit0bedf4fb30066e5e1d4342a1d3914dae7d37cba7 (patch)
tree68d8110b41afd0ebbf39167b1a4918eea667a7c5 /contrib/gcc/collect2.c
parentd4db5fb866b7ad5216abd5047774a3973b9901a9 (diff)
downloadFreeBSD-src-0bedf4fb30066e5e1d4342a1d3914dae7d37cba7.zip
FreeBSD-src-0bedf4fb30066e5e1d4342a1d3914dae7d37cba7.tar.gz
Virgin import of gcc from EGCS 1.1.2
Diffstat (limited to 'contrib/gcc/collect2.c')
-rw-r--r--contrib/gcc/collect2.c1375
1 files changed, 804 insertions, 571 deletions
diff --git a/contrib/gcc/collect2.c b/contrib/gcc/collect2.c
index 30fb49d..4fcbe73 100644
--- a/contrib/gcc/collect2.c
+++ b/contrib/gcc/collect2.c
@@ -1,8 +1,6 @@
-/* Collect static initialization info into data structures
- that can be traversed by C++ initialization and finalization
- routines.
-
- Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+/* Collect static initialization info into data structures that can be
+ traversed by C++ initialization and finalization routines.
+ Copyright (C) 1992, 93-97, 1998 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).
@@ -25,67 +23,30 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Build tables of static constructors and destructors and run ld. */
+/* Build tables of static constructors and destructors and run ld. */
#include "config.h"
-#include <sys/types.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <errno.h>
+#include "system.h"
#include <signal.h>
-#include <sys/file.h>
#include <sys/stat.h>
-#ifdef NO_WAIT_H
-#include <sys/wait.h>
-#endif
#define COLLECT
#include "demangle.h"
#include "obstack.h"
-
-#ifndef errno
-extern int errno;
-#endif
-
-#ifndef HAVE_STRERROR
-#if defined(bsd4_4)
-extern const char *const sys_errlist[];
-#else
-extern char *sys_errlist[];
-#endif
-extern int sys_nerr;
-#else
-char *strerror();
+#include "gansidecl.h"
+#ifdef __CYGWIN32__
+#include <process.h>
#endif
/* Obstack allocation and deallocation routines. */
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-#if !defined (__STDC__) && !defined (const)
-#define const
-#endif
-
#ifdef USG
#define vfork fork
#endif
-/* Add prototype support. */
-#ifndef PROTO
-#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
-#define PROTO(ARGS) ARGS
-#else
-#define PROTO(ARGS) ()
-#endif
-#endif
-
-#ifndef R_OK
-#define R_OK 4
-#define W_OK 2
-#define X_OK 1
-#endif
-
#ifndef WIFSIGNALED
#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
#endif
@@ -99,18 +60,12 @@ char *strerror();
#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
#endif
-/* On MSDOS, write temp files in current dir
- because there's no place else we can expect to use. */
-#ifdef __MSDOS__
-#ifndef P_tmpdir
-#define P_tmpdir "./"
-#endif
-#endif
+extern char *make_temp_file PROTO ((char *));
/* On certain systems, we have code that works by scanning the object file
directly. But this code uses system-specific header files and library
functions, so turn it off in a cross-compiler. Likewise, the names of
- the utilities aren't correct for a cross-compiler; we have to hope that
+ the utilities are not correct for a cross-compiler; we have to hope that
cross-versions are in the proper directories. */
#ifdef CROSS_COMPILE
@@ -123,10 +78,10 @@ char *strerror();
#undef REAL_STRIP_FILE_NAME
#endif
-/* If we can't use a special method, use the ordinary one:
+/* If we cannot use a special method, use the ordinary one:
run nm to find what symbols are present.
In a cross-compiler, this means you need a cross nm,
- but that isn't quite as unpleasant as special headers. */
+ but that is not quite as unpleasant as special headers. */
#if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
#define OBJECT_FORMAT_NONE
@@ -158,10 +113,6 @@ char *strerror();
#define MY_ISCOFF(X) ISCOFF (X)
#endif
-#ifdef XCOFF_DEBUGGING_INFO
-#define XCOFF_SCAN_LIBS
-#endif
-
#endif /* OBJECT_FORMAT_COFF */
#ifdef OBJECT_FORMAT_ROSE
@@ -200,7 +151,7 @@ char *strerror();
#define SYMBOL__MAIN __main
#endif
-#if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES || defined(XCOFF_SCAN_LIBS)
+#if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
#define SCAN_LIBRARIES
#endif
@@ -210,7 +161,7 @@ int do_collecting = 1;
int do_collecting = 0;
#endif
-/* Linked lists of constructor and destructor names. */
+/* Linked lists of constructor and destructor names. */
struct id
{
@@ -236,7 +187,7 @@ enum pass {
};
#ifndef NO_SYS_SIGLIST
-#ifndef DONT_DECLARE_SYS_SIGLIST
+#ifndef SYS_SIGLIST_DECLARED
extern char *sys_siglist[];
#endif
#endif
@@ -245,27 +196,39 @@ extern char *version_string;
int vflag; /* true if -v */
static int rflag; /* true if -r */
static int strip_flag; /* true if -s */
+#ifdef COLLECT_EXPORT_LIST
+static int export_flag; /* true if -bE */
+static int aix64_flag; /* true if -b64 */
+#endif
int debug; /* true if -debug */
static int shared_obj; /* true if -shared */
-static int temp_filename_length; /* Length of temp_filename */
-static char *temp_filename; /* Base of temp filenames */
-static char *c_file; /* <xxx>.c for constructor/destructor list. */
-static char *o_file; /* <xxx>.o for constructor/destructor list. */
-static char *export_file; /* <xxx>.x for AIX export list. */
+static char *c_file; /* <xxx>.c for constructor/destructor list. */
+static char *o_file; /* <xxx>.o for constructor/destructor list. */
+#ifdef COLLECT_EXPORT_LIST
+static char *export_file; /* <xxx>.x for AIX export list. */
+static char *import_file; /* <xxx>.p for AIX import list. */
+#endif
char *ldout; /* File for ld errors. */
static char *output_file; /* Output file for ld. */
static char *nm_file_name; /* pathname of nm */
+#ifdef LDD_SUFFIX
static char *ldd_file_name; /* pathname of ldd (or equivalent) */
+#endif
static char *strip_file_name; /* pathname of strip */
char *c_file_name; /* pathname of gcc */
static char *initname, *fininame; /* names of init and fini funcs */
static struct head constructors; /* list of constructors found */
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 */
struct obstack temporary_obstack;
struct obstack permanent_obstack;
@@ -274,17 +237,20 @@ char * temporary_firstobj;
/* Defined in the automatically-generated underscore.c. */
extern int prepends_underscore;
-extern char *getenv ();
extern char *mktemp ();
extern FILE *fdopen ();
+#ifndef GET_ENVIRONMENT
+#define GET_ENVIRONMENT(ENV_VALUE,ENV_NAME) ENV_VALUE = getenv (ENV_NAME)
+#endif
+
/* Structure to hold all the directories in which to search for files to
execute. */
struct prefix_list
{
- char *prefix; /* String to prepend to the path. */
- struct prefix_list *next; /* Next in linked list. */
+ char *prefix; /* String to prepend to the path. */
+ struct prefix_list *next; /* Next in linked list. */
};
struct path_prefix
@@ -294,13 +260,19 @@ struct path_prefix
char *name; /* Name of this list (used in config stuff) */
};
-void collect_exit PROTO((int));
-void collect_execute PROTO((char *, char **, char *));
-void dump_file PROTO((char *));
+#ifdef COLLECT_EXPORT_LIST
+/* Lists to keep libraries to be scanned for global constructors/destructors. */
+static struct head libs; /* list of libraries */
+static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
+static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
+static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
+ &libpath_lib_dirs, NULL};
+static char *libexts[3] = {"a", "so", NULL}; /* possible library extentions */
+#endif
+
+static char *my_strerror PROTO((int));
static void handler PROTO((int));
static int is_ctor_dtor PROTO((char *));
-static void choose_temp_base PROTO((void));
-static int is_in_prefix_list PROTO((struct path_prefix *, char *, int));
static char *find_a_file PROTO((struct path_prefix *, char *));
static void add_prefix PROTO((struct path_prefix *, char *));
static void prefix_from_env PROTO((char *, struct path_prefix *));
@@ -310,18 +282,30 @@ static void fork_execute PROTO((char *, char **));
static void maybe_unlink PROTO((char *));
static void add_to_list PROTO((struct head *, char *));
static void write_list PROTO((FILE *, char *, struct id *));
+#ifdef COLLECT_EXPORT_LIST
+static void dump_list PROTO((FILE *, char *, struct id *));
+#endif
+#if 0
+static void dump_prefix_list PROTO((FILE *, char *, struct prefix_list *));
+#endif
static void write_list_with_asm PROTO((FILE *, char *, struct id *));
static void write_c_file PROTO((FILE *, char *));
-static void write_export_file PROTO((FILE *));
static void scan_prog_file PROTO((char *, enum pass));
+#ifdef SCAN_LIBRARIES
static void scan_libraries PROTO((char *));
+#endif
+#ifdef COLLECT_EXPORT_LIST
+static int is_in_list PROTO((char *, struct id *));
+static void write_export_file PROTO((FILE *));
+static void write_import_file PROTO((FILE *));
+static char *resolve_lib_name PROTO((char *));
+static int use_import_list PROTO((char *));
+static int ignore_library PROTO((char *));
+#endif
char *xcalloc ();
char *xmalloc ();
-extern char *index ();
-extern char *rindex ();
-extern void free ();
#ifdef NO_DUP2
int
@@ -345,7 +329,7 @@ dup2 (oldfd, newfd)
}
#endif
-char *
+static char *
my_strerror (e)
int e;
{
@@ -379,9 +363,14 @@ collect_exit (status)
if (o_file != 0 && o_file[0])
maybe_unlink (o_file);
+#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])
{
dump_file (ldout);
@@ -395,7 +384,7 @@ collect_exit (status)
}
-/* Die when sys call fails. */
+/* Die when sys call fails. */
void
fatal_perror (string, arg1, arg2, arg3)
@@ -406,10 +395,10 @@ fatal_perror (string, arg1, arg2, arg3)
fprintf (stderr, "collect2: ");
fprintf (stderr, string, arg1, arg2, arg3);
fprintf (stderr, ": %s\n", my_strerror (e));
- collect_exit (1);
+ collect_exit (FATAL_EXIT_CODE);
}
-/* Just die. */
+/* Just die. */
void
fatal (string, arg1, arg2, arg3)
@@ -418,7 +407,7 @@ fatal (string, arg1, arg2, arg3)
fprintf (stderr, "collect2: ");
fprintf (stderr, string, arg1, arg2, arg3);
fprintf (stderr, "\n");
- collect_exit (1);
+ collect_exit (FATAL_EXIT_CODE);
}
/* Write error message. */
@@ -455,6 +444,14 @@ handler (signo)
if (ldout != 0 && ldout[0])
maybe_unlink (ldout);
+#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);
kill (getpid (), signo);
}
@@ -469,7 +466,7 @@ xcalloc (size1, size2)
return ptr;
fatal ("out of memory");
- return (char *)0;
+ return (char *) 0;
}
char *
@@ -481,7 +478,7 @@ xmalloc (size)
return ptr;
fatal ("out of memory");
- return (char *)0;
+ return (char *) 0;
}
char *
@@ -514,6 +511,39 @@ savestring (input, size)
output[size] = 0;
return output;
}
+
+/* Parse a reasonable subset of shell quoting syntax. */
+
+static char *
+extract_string (pp)
+ char **pp;
+{
+ char *p = *pp;
+ int backquote = 0;
+ int inside = 0;
+
+ for (;;)
+ {
+ char c = *p;
+ if (c == '\0')
+ break;
+ ++p;
+ if (backquote)
+ obstack_1grow (&temporary_obstack, c);
+ else if (! inside && c == ' ')
+ break;
+ else if (! inside && c == '\\')
+ backquote = 1;
+ else if (c == '\'')
+ inside = !inside;
+ else
+ obstack_1grow (&temporary_obstack, c);
+ }
+
+ obstack_1grow (&temporary_obstack, '\0');
+ *pp = p;
+ return obstack_finish (&temporary_obstack);
+}
void
dump_file (name)
@@ -528,7 +558,7 @@ dump_file (name)
{
int c;
while (c = getc (stream),
- c != EOF && (isalnum (c) || c == '_' || c == '$' || c == '.'))
+ c != EOF && (ISALNUM (c) || c == '_' || c == '$' || c == '.'))
obstack_1grow (&temporary_obstack, c);
if (obstack_object_size (&temporary_obstack) > 0)
{
@@ -570,6 +600,7 @@ dump_file (name)
break;
putc (c, stderr);
}
+ fclose (stream);
}
/* Decide whether the given symbol is:
@@ -590,17 +621,20 @@ is_ctor_dtor (s)
#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 /* Don't collect cfront initialization functions.
+#ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
cfront has its own linker procedure to collect them;
if collect2 gets them too, they get collected twice
when the cfront procedure is run and the compiler used
@@ -628,42 +662,6 @@ is_ctor_dtor (s)
}
return 0;
}
-
-
-/* Compute a string to use as the base of all temporary file names.
- It is substituted for %g. */
-
-static void
-choose_temp_base ()
-{
- char *base = getenv ("TMPDIR");
- int len;
-
- if (base == (char *)0)
- {
-#ifdef P_tmpdir
- if (access (P_tmpdir, R_OK | W_OK) == 0)
- base = P_tmpdir;
-#endif
- if (base == (char *)0)
- {
- if (access ("/usr/tmp", R_OK | W_OK) == 0)
- base = "/usr/tmp/";
- else
- base = "/tmp/";
- }
- }
-
- len = strlen (base);
- temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
- strcpy (temp_filename, base);
- if (len > 0 && temp_filename[len-1] != '/')
- temp_filename[len++] = '/';
- strcpy (temp_filename + len, "ccXXXXXX");
-
- mktemp (temp_filename);
- temp_filename_length = strlen (temp_filename);
-}
/* Routine to add variables to the environment. */
@@ -730,52 +728,10 @@ static struct path_prefix cpath, path;
static char *target_machine = TARGET_MACHINE;
#endif
-/* Names under which we were executed. Never return one of those files in our
- searches. */
-
-static struct path_prefix our_file_names;
-
-/* Determine if STRING is in PPREFIX.
-
- This utility is currently only used to look up file names. Prefix lists
- record directory names. This matters to us because the latter has a
- trailing slash, so I've added a flag to handle both. */
-
-static int
-is_in_prefix_list (pprefix, string, filep)
- struct path_prefix *pprefix;
- char *string;
- int filep;
-{
- struct prefix_list *pl;
-
- if (filep)
- {
- int len = strlen (string);
-
- for (pl = pprefix->plist; pl; pl = pl->next)
- {
- if (strncmp (pl->prefix, string, len) == 0
- && strcmp (pl->prefix + len, "/") == 0)
- return 1;
- }
- }
- else
- {
- for (pl = pprefix->plist; pl; pl = pl->next)
- {
- if (strcmp (pl->prefix, string) == 0)
- return 1;
- }
- }
-
- return 0;
-}
-
/* Search for NAME using prefix list PPREFIX. We only look for executable
files.
- Return 0 if not found, otherwise return its name, allocated with malloc. */
+ Return 0 if not found, otherwise return its name, allocated with malloc. */
static char *
find_a_file (pprefix, name)
@@ -786,6 +742,9 @@ find_a_file (pprefix, name)
struct prefix_list *pl;
int len = pprefix->max_len + strlen (name) + 1;
+ if (debug)
+ fprintf (stderr, "Looking for '%s'\n", name);
+
#ifdef EXECUTABLE_SUFFIX
len += strlen (EXECUTABLE_SUFFIX);
#endif
@@ -794,35 +753,48 @@ find_a_file (pprefix, name)
/* Determine the filename to execute (special case for absolute paths). */
- if (*name == '/')
+ if (*name == '/'
+#ifdef DIR_SEPARATOR
+ || (DIR_SEPARATOR == '\\' && name[1] == ':'
+ && (name[2] == DIR_SEPARATOR || name[2] == '/'))
+#endif
+ )
{
if (access (name, X_OK) == 0)
{
strcpy (temp, name);
+
+ if (debug)
+ fprintf (stderr, " - found: absolute path\n");
+
return temp;
}
+
+ if (debug)
+ fprintf (stderr, " - failed to locate using absolute path\n");
}
else
for (pl = pprefix->plist; pl; pl = pl->next)
{
strcpy (temp, pl->prefix);
strcat (temp, name);
- if (! is_in_prefix_list (&our_file_names, temp, 1)
- /* This is a kludge, but there seems no way around it. */
- && strcmp (temp, "./ld") != 0
- && access (temp, X_OK) == 0)
+
+ if (access (temp, X_OK) == 0)
return temp;
#ifdef EXECUTABLE_SUFFIX
/* Some systems have a suffix for executable files.
So try appending that. */
strcat (temp, EXECUTABLE_SUFFIX);
- if (! is_in_prefix_list (&our_file_names, temp, 1)
- && access (temp, X_OK) == 0)
+
+ if (access (temp, X_OK) == 0)
return temp;
#endif
}
+ if (debug && pprefix->plist == NULL)
+ fprintf (stderr, " - failed: no entries in prefix list\n");
+
free (temp);
return 0;
}
@@ -870,7 +842,8 @@ prefix_from_env (env, pprefix)
char *env;
struct path_prefix *pprefix;
{
- char *p = getenv (env);
+ char *p;
+ GET_ENVIRONMENT (p, env);
if (p)
prefix_from_string (p, pprefix);
@@ -884,6 +857,9 @@ prefix_from_string (p, pprefix)
char *startp, *endp;
char *nstore = (char *) xmalloc (strlen (p) + 3);
+ if (debug)
+ fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
+
startp = endp = p;
while (1)
{
@@ -902,6 +878,9 @@ prefix_from_string (p, pprefix)
else
nstore[endp-startp] = 0;
+ if (debug)
+ fprintf (stderr, " - add prefix: %s\n", nstore);
+
add_prefix (pprefix, nstore);
if (*endp == 0)
break;
@@ -912,7 +891,7 @@ prefix_from_string (p, pprefix)
}
}
-/* Main program. */
+/* Main program. */
int
main (argc, argv)
@@ -922,7 +901,6 @@ main (argc, argv)
char *ld_suffix = "ld";
char *full_ld_suffix = ld_suffix;
char *real_ld_suffix = "real-ld";
- char *full_real_ld_suffix = real_ld_suffix;
char *collect_ld_suffix = "collect-ld";
char *nm_suffix = "nm";
char *full_nm_suffix = nm_suffix;
@@ -937,10 +915,12 @@ main (argc, argv)
char *gstrip_suffix = "gstrip";
char *full_gstrip_suffix = gstrip_suffix;
char *arg;
- FILE *outf, *exportf;
+ FILE *outf;
+#ifdef COLLECT_EXPORT_LIST
+ FILE *exportf;
+ FILE *importf;
+#endif
char *ld_file_name;
- char *collect_name;
- char *collect_names;
char *p;
char **c_argv;
char **c_ptr;
@@ -951,75 +931,44 @@ main (argc, argv)
char **object_lst = (char **) xcalloc (sizeof (char *), argc);
char **object = object_lst;
int first_file;
- int num_c_args = argc+7;
+ int num_c_args = argc+9;
#ifdef DEBUG
debug = 1;
- vflag = 1;
#endif
+ /* Parse command line early for instances of -debug. This allows
+ the debug flag to be set before functions like find_a_file()
+ are called. */
+ {
+ int i;
+
+ for (i = 1; argv[i] != NULL; i ++)
+ if (! strcmp (argv[i], "-debug"))
+ debug = 1;
+ vflag = debug;
+ }
+
+#ifndef DEFAULT_A_OUT_NAME
output_file = "a.out";
+#else
+ output_file = DEFAULT_A_OUT_NAME;
+#endif
obstack_begin (&temporary_obstack, 0);
obstack_begin (&permanent_obstack, 0);
temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
- current_demangling_style = gnu_demangling;
-
- /* We must check that we do not call ourselves in an infinite
- recursion loop. We append the name used for us to the COLLECT_NAMES
- environment variable.
-
- In practice, collect will rarely invoke itself. This can happen now
- that we are no longer called gld. A perfect example is when running
- gcc in a build directory that has been installed. When looking for
- ld's, we'll find our installed version and believe that's the real ld. */
-
- /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the
- previous version of collect (the one that used COLLECT_NAME and only
- handled two levels of recursion). If we don't we may mutually recurse
- forever. This can happen (I think) when bootstrapping the old version
- and a new one is installed (rare, but we should handle it).
- ??? Hopefully references to COLLECT_NAME can be removed at some point. */
-
- collect_name = (char *) getenv ("COLLECT_NAME");
- collect_names = (char *) getenv ("COLLECT_NAMES");
-
- p = (char *) xmalloc (strlen ("COLLECT_NAMES=")
- + (collect_name ? strlen (collect_name) + 1 : 0)
- + (collect_names ? strlen (collect_names) + 1 : 0)
- + strlen (argv[0]) + 1);
- strcpy (p, "COLLECT_NAMES=");
- if (collect_name != 0)
- sprintf (p + strlen (p), "%s%c", collect_name, PATH_SEPARATOR);
- if (collect_names != 0)
- sprintf (p + strlen (p), "%s%c", collect_names, PATH_SEPARATOR);
- strcat (p, argv[0]);
- putenv (p);
-
- prefix_from_env ("COLLECT_NAMES", &our_file_names);
-
- /* Set environment variable COLLECT_NAME to our name so the previous version
- of collect won't find us. If it does we'll mutually recurse forever.
- This can happen when bootstrapping the new version and an old version is
- installed.
- ??? Hopefully this bit of code can be removed at some point. */
-
- p = xmalloc (strlen ("COLLECT_NAME=") + strlen (argv[0]) + 1);
- sprintf (p, "COLLECT_NAME=%s", argv[0]);
- putenv (p);
-
- p = (char *) getenv ("COLLECT_GCC_OPTIONS");
- if (p)
- while (*p)
- {
- char *q = p;
- while (*q && *q != ' ') q++;
- if (*p == '-' && p[1] == 'm')
- num_c_args++;
- if (*q) q++;
- p = q;
- }
+ current_demangling_style = gnu_demangling;
+ p = getenv ("COLLECT_GCC_OPTIONS");
+ while (p && *p)
+ {
+ char *q = extract_string (&p);
+ if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
+ num_c_args++;
+ }
+ obstack_free (&temporary_obstack, temporary_firstobj);
+ ++num_c_args;
c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
@@ -1054,7 +1003,7 @@ main (argc, argv)
#ifdef CROSS_COMPILE
/* If we look for a program in the compiler directories, we just use
the short name, since these directories are already system-specific.
- But it we look for a took in the system directories, we need to
+ But it we look for a program in the system directories, we need to
qualify the program name with the target machine. */
full_ld_suffix
@@ -1063,12 +1012,6 @@ main (argc, argv)
strcat (full_ld_suffix, "-");
strcat (full_ld_suffix, ld_suffix);
- full_real_ld_suffix
- = xcalloc (strlen (real_ld_suffix) + strlen (target_machine) + 2, 1);
- strcpy (full_real_ld_suffix, target_machine);
- strcat (full_real_ld_suffix, "-");
- strcat (full_real_ld_suffix, real_ld_suffix);
-
#if 0
full_gld_suffix
= xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);
@@ -1131,18 +1074,6 @@ main (argc, argv)
if (ld_file_name == 0)
ld_file_name = find_a_file (&path, full_ld_suffix);
- /* If we've invoked ourselves, try again with LD_FILE_NAME. */
-
- if (collect_names != 0)
- {
- if (ld_file_name != 0)
- {
- argv[0] = ld_file_name;
- execvp (argv[0], argv);
- }
- fatal ("cannot find `ld'");
- }
-
#ifdef REAL_NM_FILE_NAME
nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
if (nm_file_name == 0)
@@ -1198,21 +1129,47 @@ main (argc, argv)
*ld1++ = *ld2++ = ld_file_name;
- /* Make temp file names. */
- choose_temp_base ();
- c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);
- o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);
- export_file = xmalloc (temp_filename_length + sizeof (".x"));
- ldout = xmalloc (temp_filename_length + sizeof (".ld"));
- sprintf (ldout, "%s.ld", temp_filename);
- sprintf (c_file, "%s.c", temp_filename);
- sprintf (o_file, "%s.o", temp_filename);
- sprintf (export_file, "%s.x", temp_filename);
+ /* Make temp file names. */
+ c_file = make_temp_file (".c");
+ 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++ = "-x";
+ *c_ptr++ = "c";
*c_ptr++ = "-c";
*c_ptr++ = "-o";
*c_ptr++ = o_file;
+#ifdef COLLECT_EXPORT_LIST
+ /* Generate a list of directories from LIBPATH. */
+ prefix_from_env ("LIBPATH", &libpath_lib_dirs);
+ /* Add to this list also two standard directories where
+ AIX loader always searches for libraries. */
+ add_prefix (&libpath_lib_dirs, "/lib");
+ add_prefix (&libpath_lib_dirs, "/usr/lib");
+#endif
+
+ /* Get any options that the upper GCC wants to pass to the sub-GCC.
+
+ AIX support needs to know if -shared has been specified before
+ parsing commandline arguments. */
+
+ p = getenv ("COLLECT_GCC_OPTIONS");
+ while (p && *p)
+ {
+ char *q = extract_string (&p);
+ if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
+ *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
+ if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0)
+ shared_obj = 1;
+ }
+ obstack_free (&temporary_obstack, temporary_firstobj);
+ *c_ptr++ = "-fno-exceptions";
+
/* !!! When GCC calls collect2,
it does not know whether it is calling collect2 or ld.
So collect2 cannot meaningfully understand any options
@@ -1220,11 +1177,11 @@ main (argc, argv)
If you propose to make GCC pass some other option,
just imagine what will happen if ld is really ld!!! */
- /* Parse arguments. Remember output file spec, pass the rest to ld. */
+ /* Parse arguments. Remember output file spec, pass the rest to ld. */
/* After the first file, put in the c++ rt0. */
first_file = 1;
- while ((arg = *++argv) != (char *)0)
+ while ((arg = *++argv) != (char *) 0)
{
*ld1++ = *ld2++ = arg;
@@ -1232,11 +1189,21 @@ main (argc, argv)
{
switch (arg[1])
{
+#ifdef COLLECT_EXPORT_LIST
+ /* We want to disable automatic exports on AIX when user
+ explicitly puts an export list in command line */
+ case 'b':
+ if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
+ export_flag = 1;
+ if (arg[2] == '6' && arg[3] == '4')
+ aix64_flag = 1;
+ break;
+#endif
+
case 'd':
if (!strcmp (arg, "-debug"))
{
- debug = 1;
- vflag = 1;
+ /* Already parsed. */
ld1--;
ld2--;
}
@@ -1251,7 +1218,31 @@ main (argc, argv)
*ld2++ = o_file;
*ld2++ = arg;
}
+#ifdef COLLECT_EXPORT_LIST
+ {
+ /* Resolving full library name. */
+ 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);
+ }
+#endif
+ break;
+
+#ifdef COLLECT_EXPORT_LIST
+ /* Saving directories where to search for libraries. */
+ case 'L':
+ add_prefix (&cmdline_lib_dirs, arg+2);
break;
+#endif
case 'o':
if (arg[2] == '\0')
@@ -1269,7 +1260,7 @@ main (argc, argv)
if (arg[2] == '\0' && do_collecting)
{
/* We must strip after the nm run, otherwise C++ linking
- won't work. Thus we strip in the second ld run, or
+ will not work. Thus we strip in the second ld run, or
else with strip if there is no second ld run. */
strip_flag = 1;
ld1--;
@@ -1282,8 +1273,9 @@ main (argc, argv)
break;
}
}
- else if ((p = rindex (arg, '.')) != (char *)0
- && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0))
+ else if ((p = rindex (arg, '.')) != (char *) 0
+ && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
+ || strcmp (p, ".so") == 0))
{
if (first_file)
{
@@ -1300,47 +1292,71 @@ main (argc, argv)
}
if (p[1] == 'o')
*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);
+ }
+#endif
}
}
- /* Get any options that the upper GCC wants to pass to the sub-GCC. */
- p = (char *) getenv ("COLLECT_GCC_OPTIONS");
- if (p)
- while (*p)
- {
- char *q = p;
- while (*q && *q != ' ') q++;
- if (*p == '-' && (p[1] == 'm' || p[1] == 'f'))
- *c_ptr++ = savestring (p, q - p);
- if (strncmp (p, "-shared", sizeof ("shared") - 1) == 0)
- shared_obj = 1;
-
- if (*q) q++;
- p = q;
- }
-
#ifdef COLLECT_EXPORT_LIST
+ /* This is added only for debugging purposes. */
+ if (debug)
+ {
+ fprintf (stderr, "List of libraries:\n");
+ dump_list (stderr, "\t", libs.first);
+ }
+
/* The AIX linker will discard static constructors in object files if
nothing else in the file is referenced, so look at them first. */
- while (object_lst < object)
- scan_prog_file (*object_lst++, PASS_OBJ);
-
{
- char *buf = alloca (strlen (export_file) + 5);
- sprintf (buf, "-bE:%s", export_file);
- *ld1++ = buf;
- *ld2++ = buf;
+ char **export_object_lst = object_lst;
+ while (export_object_lst < object)
+ scan_prog_file (*export_object_lst++, PASS_OBJ);
+ }
+ {
+ struct id *list = libs.first;
+ for (; list; list = list->next)
+ scan_prog_file (list->name, PASS_FIRST);
+ }
+ {
+ char *buf1 = alloca (strlen (export_file) + 5);
+ char *buf2 = alloca (strlen (import_file) + 5);
+ sprintf (buf1, "-bE:%s", export_file);
+ sprintf (buf2, "-bI:%s", import_file);
+ *ld1++ = buf1;
+ *ld2++ = buf1;
+ *ld1++ = buf2;
+ *ld2++ = buf2;
exportf = fopen (export_file, "w");
- if (exportf == (FILE *)0)
+ if (exportf == (FILE *) 0)
fatal_perror ("%s", export_file);
write_export_file (exportf);
if (fclose (exportf))
fatal_perror ("closing %s", export_file);
+ importf = fopen (import_file, "w");
+ if (importf == (FILE *) 0)
+ fatal_perror ("%s", import_file);
+ write_import_file (importf);
+ if (fclose (importf))
+ fatal_perror ("closing %s", import_file);
}
#endif
*c_ptr++ = c_file;
- *object = *c_ptr = *ld1 = (char *)0;
+ *object = *c_ptr = *ld1 = (char *) 0;
if (vflag)
{
@@ -1371,10 +1387,6 @@ main (argc, argv)
fprintf (stderr, "o_file = %s\n",
(o_file ? o_file : "not found"));
- ptr = getenv ("COLLECT_NAMES");
- if (ptr)
- fprintf (stderr, "COLLECT_NAMES = %s\n", ptr);
-
ptr = getenv ("COLLECT_GCC_OPTIONS");
if (ptr)
fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
@@ -1394,23 +1406,42 @@ main (argc, argv)
fprintf (stderr, "\n");
}
- /* Load the program, searching all libraries. */
+ /* Load the program, searching all libraries and attempting to provide
+ undefined symbols from repository information. */
- collect_execute ("ld", ld1_argv, ldout);
- do_wait ("ld");
- dump_file (ldout);
- unlink (ldout);
+ /* On AIX we do this later. */
+#ifndef COLLECT_EXPORT_LIST
+ do_tlink (ld1_argv, object_lst);
+#endif
- /* If -r or they'll be run via some other method, don't build the
- constructor or destructor list, just return now. */
- if (rflag || ! do_collecting)
- return 0;
+ /* If -r or they will be run via some other method, do not build the
+ constructor or destructor list, just return now. */
+ if (rflag
+#ifndef COLLECT_EXPORT_LIST
+ || ! do_collecting
+#endif
+ )
+ {
+#ifdef COLLECT_EXPORT_LIST
+ /* 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);
+ return 0;
+ }
/* Examine the namelist with nm and search it for static constructors
and destructors to call.
- Write the constructor and destructor tables to a .s file and reload. */
+ Write the constructor and destructor tables to a .s file and reload. */
+ /* On AIX we already done scanning for global constructors/destructors. */
+#ifndef COLLECT_EXPORT_LIST
scan_prog_file (output_file, PASS_FIRST);
+#endif
#ifdef SCAN_LIBRARIES
scan_libraries (output_file);
@@ -1423,14 +1454,19 @@ main (argc, argv)
}
if (constructors.number == 0 && destructors.number == 0
-#ifdef LDD_SUFFIX
+ && frame_tables.number == 0
+#if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
/* If we will be running these functions ourselves, we want to emit
- stubs into the shared library so that we don't have to relink
+ stubs into the shared library so that we do not have to relink
dependent programs when we add static objects. */
&& ! shared_obj
#endif
)
{
+#ifdef COLLECT_EXPORT_LIST
+ /* Doing tlink without additional code generation */
+ do_tlink (ld1_argv, object_lst);
+#endif
/* Strip now if it was requested on the command line. */
if (strip_flag)
{
@@ -1443,13 +1479,16 @@ main (argc, argv)
#ifdef COLLECT_EXPORT_LIST
maybe_unlink (export_file);
+ maybe_unlink (import_file);
#endif
+ maybe_unlink (c_file);
+ maybe_unlink (o_file);
return 0;
}
maybe_unlink(output_file);
outf = fopen (c_file, "w");
- if (outf == (FILE *)0)
+ if (outf == (FILE *) 0)
fatal_perror ("%s", c_file);
write_c_file (outf, c_file);
@@ -1464,7 +1503,7 @@ main (argc, argv)
*ld2++ = LD_FINI_SWITCH;
*ld2++ = fininame;
#endif
- *ld2 = (char*)0;
+ *ld2 = (char*) 0;
#ifdef COLLECT_EXPORT_LIST
if (shared_obj)
@@ -1474,7 +1513,7 @@ main (argc, argv)
add_to_list (&exports, "_GLOBAL__DI");
add_to_list (&exports, "_GLOBAL__DD");
exportf = fopen (export_file, "w");
- if (exportf == (FILE *)0)
+ if (exportf == (FILE *) 0)
fatal_perror ("%s", export_file);
write_export_file (exportf);
if (fclose (exportf))
@@ -1496,23 +1535,34 @@ main (argc, argv)
}
/* Assemble the constructor and destructor tables.
- Link the tables in with the rest of the program. */
+ Link the tables in with the rest of the program. */
fork_execute ("gcc", c_argv);
+#ifdef COLLECT_EXPORT_LIST
+ /* On AIX we must call tlink because of possible templates resolution */
+ do_tlink (ld2_argv, object_lst);
+#else
+ /* Otherwise, simply call ld because tlink is already done */
fork_execute ("ld", ld2_argv);
/* Let scan_prog_file do any final mods (OSF/rose needs this for
constructors/destructors in shared libraries. */
scan_prog_file (output_file, PASS_SECOND);
+#endif
maybe_unlink (c_file);
maybe_unlink (o_file);
+
+#ifdef COLLECT_EXPORT_LIST
maybe_unlink (export_file);
+ maybe_unlink (import_file);
+#endif
+
return 0;
}
-/* Wait for a process to finish, and exit if a non-zero status is found. */
+/* Wait for a process to finish, and exit if a non-zero status is found. */
int
collect_wait (prog)
@@ -1539,7 +1589,7 @@ collect_wait (prog)
(status & 0200) ? ", core dumped" : "");
#endif
- collect_exit (127);
+ collect_exit (FATAL_EXIT_CODE);
}
if (WIFEXITED (status))
@@ -1581,7 +1631,7 @@ collect_execute (prog, argv, redir)
else
fprintf (stderr, "[cannot find %s]", prog);
- for (p_argv = &argv[1]; (str = *p_argv) != (char *)0; p_argv++)
+ for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
fprintf (stderr, " %s", str);
fprintf (stderr, "\n");
@@ -1590,12 +1640,13 @@ collect_execute (prog, argv, redir)
fflush (stdout);
fflush (stderr);
- /* If we can't find a program we need, complain error. Do this here
- since we might not end up needing something that we couldn't find. */
+ /* If we cannot find a program we need, complain error. Do this here
+ since we might not end up needing something that we could not find. */
if (argv[0] == 0)
fatal ("cannot find `%s'", prog);
+#ifndef __CYGWIN32__
pid = vfork ();
if (pid == -1)
{
@@ -1612,14 +1663,19 @@ collect_execute (prog, argv, redir)
{
unlink (redir);
if (freopen (redir, "a", stdout) == NULL)
- fatal_perror ("redirecting stdout");
+ fatal_perror ("redirecting stdout: %s", redir);
if (freopen (redir, "a", stderr) == NULL)
- fatal_perror ("redirecting stderr");
+ fatal_perror ("redirecting stderr: %s", redir);
}
execvp (argv[0], argv);
fatal_perror ("executing %s", prog);
}
+#else
+ pid = _spawnvp (_P_NOWAIT, argv[0], argv);
+ if (pid == -1)
+ fatal ("spawnvp failed");
+#endif
}
static void
@@ -1694,6 +1750,53 @@ write_list (stream, prefix, list)
}
}
+#ifdef COLLECT_EXPORT_LIST
+/* This function is really used only on AIX, but may be useful. */
+static int
+is_in_list (prefix, list)
+ char *prefix;
+ struct id *list;
+{
+ while (list)
+ {
+ if (!strcmp (prefix, list->name)) return 1;
+ list = list->next;
+ }
+ return 0;
+}
+#endif
+
+/* Added for debugging purpose. */
+#ifdef COLLECT_EXPORT_LIST
+static void
+dump_list (stream, prefix, list)
+ FILE *stream;
+ char *prefix;
+ struct id *list;
+{
+ while (list)
+ {
+ fprintf (stream, "%s%s,\n", prefix, list->name);
+ list = list->next;
+ }
+}
+#endif
+
+#if 0
+static void
+dump_prefix_list (stream, prefix, list)
+ FILE *stream;
+ char *prefix;
+ struct prefix_list *list;
+{
+ while (list)
+ {
+ fprintf (stream, "%s%s,\n", prefix, list->prefix);
+ list = list->next;
+ }
+}
+#endif
+
static void
write_list_with_asm (stream, prefix, list)
FILE *stream;
@@ -1717,6 +1820,7 @@ write_c_file_stat (stream, name)
char *name;
{
char *prefix, *p, *q;
+ int frames = (frame_tables.number > 0);
/* Figure out name of output_file, stripping off .so version. */
p = rindex (output_file, '/');
@@ -1749,7 +1853,7 @@ write_c_file_stat (stream, name)
strncpy (prefix, p, q - p);
prefix[q - p] = 0;
for (q = prefix; *q; q++)
- if (!isalnum (*q))
+ if (!ISALNUM (*q))
*q = '_';
if (debug)
fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n",
@@ -1770,15 +1874,49 @@ write_c_file_stat (stream, name)
fprintf (stream, "static int count;\n");
fprintf (stream, "typedef void entry_pt();\n");
write_list_with_asm (stream, "extern entry_pt ", constructors.first);
+
+ if (frames)
+ {
+ write_list_with_asm (stream, "extern void *", frame_tables.first);
+
+ fprintf (stream, "\tstatic void *frame_table[] = {\n");
+ write_list (stream, "\t\t&", frame_tables.first);
+ fprintf (stream, "\t0\n};\n");
+
+ /* This must match what's in frame.h. */
+ fprintf (stream, "struct object {\n");
+ fprintf (stream, " void *pc_begin;\n");
+ fprintf (stream, " void *pc_end;\n");
+ fprintf (stream, " void *fde_begin;\n");
+ fprintf (stream, " void *fde_array;\n");
+ fprintf (stream, " __SIZE_TYPE__ count;\n");
+ fprintf (stream, " struct object *next;\n");
+ fprintf (stream, "};\n");
+
+ fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
+ fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
+
+ fprintf (stream, "static void reg_frame () {\n");
+ fprintf (stream, "\tstatic struct object ob;\n");
+ fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
+ fprintf (stream, "\t}\n");
+
+ fprintf (stream, "static void dereg_frame () {\n");
+ fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
+ fprintf (stream, "\t}\n");
+ }
+
fprintf (stream, "void %s() {\n", initname);
- if (constructors.number > 0)
+ if (constructors.number > 0 || frames)
{
fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
write_list (stream, "\t\t", constructors.first);
+ if (frames)
+ fprintf (stream, "\treg_frame,\n");
fprintf (stream, "\t};\n");
fprintf (stream, "\tentry_pt **p;\n");
fprintf (stream, "\tif (count++ != 0) return;\n");
- fprintf (stream, "\tp = ctors + %d;\n", constructors.number);
+ fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
}
else
@@ -1786,16 +1924,18 @@ write_c_file_stat (stream, name)
fprintf (stream, "}\n");
write_list_with_asm (stream, "extern entry_pt ", destructors.first);
fprintf (stream, "void %s() {\n", fininame);
- if (destructors.number > 0)
+ if (destructors.number > 0 || frames)
{
fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
write_list (stream, "\t\t", destructors.first);
+ if (frames)
+ fprintf (stream, "\tdereg_frame,\n");
fprintf (stream, "\t};\n");
fprintf (stream, "\tentry_pt **p;\n");
fprintf (stream, "\tif (--count != 0) return;\n");
fprintf (stream, "\tp = dtors;\n");
fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
- destructors.number);
+ destructors.number + frames);
}
fprintf (stream, "}\n");
@@ -1806,8 +1946,9 @@ write_c_file_stat (stream, name)
}
}
-/* Write the constructor/destructor tables. */
+/* Write the constructor/destructor tables. */
+#ifndef LD_INIT_SWITCH
static void
write_c_file_glob (stream, name)
FILE *stream;
@@ -1815,39 +1956,80 @@ write_c_file_glob (stream, name)
{
/* Write the tables as C code */
+ int frames = (frame_tables.number > 0);
+
fprintf (stream, "typedef void entry_pt();\n\n");
write_list_with_asm (stream, "extern entry_pt ", constructors.first);
-
+
+ if (frames)
+ {
+ write_list_with_asm (stream, "extern void *", frame_tables.first);
+
+ fprintf (stream, "\tstatic void *frame_table[] = {\n");
+ write_list (stream, "\t\t&", frame_tables.first);
+ fprintf (stream, "\t0\n};\n");
+
+ /* This must match what's in frame.h. */
+ fprintf (stream, "struct object {\n");
+ fprintf (stream, " void *pc_begin;\n");
+ fprintf (stream, " void *pc_end;\n");
+ fprintf (stream, " void *fde_begin;\n");
+ fprintf (stream, " void *fde_array;\n");
+ fprintf (stream, " __SIZE_TYPE__ count;\n");
+ fprintf (stream, " struct object *next;\n");
+ fprintf (stream, "};\n");
+
+ fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
+ fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
+
+ fprintf (stream, "static void reg_frame () {\n");
+ fprintf (stream, "\tstatic struct object ob;\n");
+ fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
+ fprintf (stream, "\t}\n");
+
+ fprintf (stream, "static void dereg_frame () {\n");
+ fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
+ fprintf (stream, "\t}\n");
+ }
+
fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
- fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number);
+ fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
write_list (stream, "\t", constructors.first);
+ if (frames)
+ fprintf (stream, "\treg_frame,\n");
fprintf (stream, "\t0\n};\n\n");
write_list_with_asm (stream, "extern entry_pt ", destructors.first);
fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
- fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number);
+ fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
write_list (stream, "\t", destructors.first);
+ if (frames)
+ fprintf (stream, "\tdereg_frame,\n");
fprintf (stream, "\t0\n};\n\n");
fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
}
+#endif /* ! LD_INIT_SWITCH */
static void
write_c_file (stream, name)
FILE *stream;
char *name;
{
+ fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
#ifndef LD_INIT_SWITCH
if (! shared_obj)
write_c_file_glob (stream, name);
else
#endif
write_c_file_stat (stream, name);
+ fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
}
+#ifdef COLLECT_EXPORT_LIST
static void
write_export_file (stream)
FILE *stream;
@@ -1856,6 +2038,17 @@ write_export_file (stream)
for (; list; list = list->next)
fprintf (stream, "%s\n", list->name);
}
+
+static void
+write_import_file (stream)
+ FILE *stream;
+{
+ struct id *list = imports.first;
+ fprintf (stream, "%s\n", "#! .");
+ for (; list; list = list->next)
+ fprintf (stream, "%s\n", list->name);
+}
+#endif
#ifdef OBJECT_FORMAT_NONE
@@ -1885,7 +2078,7 @@ scan_prog_file (prog_name, which_pass)
if (which_pass == PASS_SECOND)
return;
- /* If we don't have an `nm', complain. */
+ /* If we do not have an `nm', complain. */
if (nm_file_name == 0)
fatal ("cannot find `nm'");
@@ -1894,13 +2087,13 @@ scan_prog_file (prog_name, which_pass)
nm_argv[argc++] = NM_FLAGS;
nm_argv[argc++] = prog_name;
- nm_argv[argc++] = (char *)0;
+ nm_argv[argc++] = (char *) 0;
if (pipe (pipe_fd) < 0)
fatal_perror ("pipe");
inf = fdopen (pipe_fd[0], "r");
- if (inf == (FILE *)0)
+ if (inf == (FILE *) 0)
fatal_perror ("fdopen");
/* Trace if needed. */
@@ -1909,7 +2102,7 @@ scan_prog_file (prog_name, which_pass)
char **p_argv;
char *str;
- for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *)0; p_argv++)
+ for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
fprintf (stderr, " %s", str);
fprintf (stderr, "\n");
@@ -1958,13 +2151,13 @@ scan_prog_file (prog_name, which_pass)
fprintf (stderr, "\nnm output with constructors/destructors.\n");
/* Read each line of nm output. */
- while (fgets (buf, sizeof buf, inf) != (char *)0)
+ while (fgets (buf, sizeof buf, inf) != (char *) 0)
{
int ch, ch2;
char *name, *end;
/* If it contains a constructor or destructor name, add the name
- to the appropriate list. */
+ to the appropriate list. */
for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
@@ -1975,8 +2168,8 @@ scan_prog_file (prog_name, which_pass)
name = p;
/* Find the end of the symbol name.
- Don't include `|', because Encore nm can tack that on the end. */
- for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';
+ Do not include `|', because Encore nm can tack that on the end. */
+ for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
end++)
continue;
@@ -2010,6 +2203,10 @@ scan_prog_file (prog_name, which_pass)
#endif
break;
+ case 5:
+ if (which_pass != PASS_LIB)
+ add_to_list (&frame_tables, name);
+
default: /* not a constructor or destructor */
continue;
}
@@ -2043,7 +2240,7 @@ scan_prog_file (prog_name, which_pass)
#include <link.h>
#include <sys/mman.h>
#include <sys/param.h>
-#include <sys/unistd.h>
+#include <unistd.h>
#include <sys/dir.h>
/* pointers to the object file */
@@ -2095,7 +2292,7 @@ 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 won't be used. */
+ invalid extensions must go last in the sort, so that they will not be used. */
static int
libcompare (d1, d2)
@@ -2106,7 +2303,7 @@ libcompare (d1, d2)
char *e2 = (*d2)->d_name + i2;
while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
- && e1[1] && isdigit (e1[1]) && e2[1] && isdigit (e2[1]))
+ && e1[1] && ISDIGIT (e1[1]) && e2[1] && ISDIGIT (e2[1]))
{
++e1;
++e2;
@@ -2119,7 +2316,7 @@ libcompare (d1, d2)
if (*e1)
{
/* It has a valid numeric extension, prefer this one. */
- if (*e1 == '.' && e1[1] && isdigit (e1[1]))
+ if (*e1 == '.' && e1[1] && ISDIGIT (e1[1]))
return 1;
/* It has a invalid numeric extension, must prefer the other one. */
else
@@ -2128,7 +2325,7 @@ libcompare (d1, d2)
else if (*e2)
{
/* It has a valid numeric extension, prefer this one. */
- if (*e2 == '.' && e2[1] && isdigit (e2[1]))
+ if (*e2 == '.' && e2[1] && ISDIGIT (e2[1]))
return -1;
/* It has a invalid numeric extension, must prefer the other one. */
else
@@ -2323,7 +2520,7 @@ scan_libraries (prog_name)
char buf[1024];
FILE *inf;
- /* If we don't have an `ldd', complain. */
+ /* If we do not have an `ldd', complain. */
if (ldd_file_name == 0)
{
error ("cannot find `ldd'");
@@ -2401,7 +2598,7 @@ scan_libraries (prog_name)
int ch, ch2;
char *name, *end, *p = buf;
- /* Extract names of libraries and add to list. */
+ /* Extract names of libraries and add to list. */
PARSE_LDD_OUTPUT (p);
if (p == 0)
continue;
@@ -2410,9 +2607,9 @@ scan_libraries (prog_name)
if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
fatal ("dynamic dependency %s not found", buf);
- /* Find the end of the symbol name. */
+ /* Find the end of the symbol name. */
for (end = p;
- (ch2 = *end) != '\0' && ch2 != '\n' && !isspace (ch2) && ch2 != '|';
+ (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
end++)
continue;
*end = '\0';
@@ -2468,11 +2665,16 @@ scan_libraries (prog_name)
# define GCC_SYMENT SYMENT
# define GCC_OK_SYMBOL(X) \
(((X).n_sclass == C_EXT) && \
- (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
- ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
+ ((X).n_scnum > N_UNDEF) && \
+ (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
+ ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
+# define GCC_UNDEF_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
-# define GCC_CHECK_HDR(X) (1)
+# define GCC_CHECK_HDR(X) \
+ ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
+ || (HEADER (X).f_magic == 0757 && aix64_flag))
#endif
extern char *ldgetname ();
@@ -2493,246 +2695,277 @@ scan_prog_file (prog_name, which_pass)
{
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;
- if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
- fatal ("%s: can't open as COFF file", prog_name);
-
- if (!MY_ISCOFF (HEADER (ldptr).f_magic))
- fatal ("%s: not a COFF file", prog_name);
+#ifdef COLLECT_EXPORT_LIST
+ /* We do not need scanning for some standard C libraries. */
+ if (which_pass == PASS_FIRST && ignore_library (prog_name))
+ return;
- if (GCC_CHECK_HDR (ldptr))
+ /* On AIX we have a loop, because there is not much difference
+ between an object and an archive. This trick allows us to
+ eliminate scan_libraries() function. */
+ do
{
- sym_count = GCC_SYMBOLS (ldptr);
- sym_index = GCC_SYMZERO (ldptr);
- while (sym_index < sym_count)
+#endif
+ if ((ldptr = ldopen (prog_name, ldptr)) != NULL)
{
- GCC_SYMENT symbol;
-
- if (ldtbread (ldptr, sym_index, &symbol) <= 0)
- break;
- sym_index += GCC_SYMINC (symbol);
+ if (! MY_ISCOFF (HEADER (ldptr).f_magic))
+ fatal ("%s: not a COFF file", prog_name);
- if (GCC_OK_SYMBOL (symbol))
+ if (GCC_CHECK_HDR (ldptr))
{
- char *name;
+ sym_count = GCC_SYMBOLS (ldptr);
+ sym_index = GCC_SYMZERO (ldptr);
- if ((name = ldgetname (ldptr, &symbol)) == NULL)
- continue; /* should never happen */
+#ifdef COLLECT_EXPORT_LIST
+ /* Is current archive member a shared object? */
+ is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
+#endif
+
+ while (sym_index < sym_count)
+ {
+ GCC_SYMENT symbol;
+
+ if (ldtbread (ldptr, sym_index, &symbol) <= 0)
+ break;
+ sym_index += GCC_SYMINC (symbol);
+
+ if (GCC_OK_SYMBOL (symbol))
+ {
+ char *name;
+
+ if ((name = ldgetname (ldptr, &symbol)) == NULL)
+ continue; /* should never happen */
#ifdef XCOFF_DEBUGGING_INFO
- /* All AIX function names have a duplicate entry beginning
- with a dot. */
- if (*name == '.')
- ++name;
+ /* All AIX function names have a duplicate entry
+ beginning with a dot. */
+ if (*name == '.')
+ ++name;
#endif
- switch (is_ctor_dtor (name))
- {
- case 1:
- add_to_list (&constructors, name);
- if (which_pass == PASS_OBJ)
- add_to_list (&exports, name);
- break;
+ switch (is_ctor_dtor (name))
+ {
+ case 1:
+ 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);
+#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:
- add_to_list (&destructors, name);
- if (which_pass == PASS_OBJ)
- add_to_list (&exports, name);
- break;
+#ifdef COLLECT_EXPORT_LIST
+ case 3:
+ if (is_shared)
+ add_to_list (&constructors, name);
+ break;
- default: /* not a constructor or destructor */
- continue;
- }
+ case 4:
+ if (is_shared)
+ add_to_list (&destructors, name);
+ break;
+#endif
+
+ 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. */
+ 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)
- 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);
+ if (debug)
+ 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 = %5d, index = %5d, name = %s\n",
- symbol.iss, symbol.value, symbol.index, name);
+ 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
+ else
+ {
+ /* If archive contains both 32-bit and 64-bit objects,
+ we want to skip objects in other mode so mismatch normal. */
+ if (debug)
+ fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
+ prog_name, HEADER (ldptr).f_magic, aix64_flag);
}
+#endif
+ }
+ else
+ {
+ fatal ("%s: cannot open as COFF file", prog_name);
}
+#ifdef COLLECT_EXPORT_LIST
+ /* On AIX loop continues while there are more members in archive. */
}
-
+ while (ldclose (ldptr) == FAILURE);
+#else
+ /* Otherwise we simply close ldptr. */
(void) ldclose(ldptr);
+#endif
}
-#ifdef XCOFF_SCAN_LIBS
-/* Scan imported AIX libraries for GCC static ctors and dtors.
- FIXME: it is possible to link an executable without the actual import
- library by using an "import file" - a text file listing symbols
- exported by a library. To support this, we would have to scan
- import files as well as actual shared binaries to find GCC ctors.
- TODO: use memory mapping instead of 'ld' routines, files are already
- memory mapped, but we could eliminate the extra in-memory copies.
- Is it worth the effort? */
-static void
-scan_libraries (prog_name)
+#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)
char *prog_name;
{
- LDFILE *ldptr;
- SCNHDR ldsh;
- static struct path_prefix libpath; /* we should only do this once */
-
- if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
- fatal ("%s: can't open as COFF file", prog_name);
-
- if (!MY_ISCOFF (HEADER (ldptr).f_magic))
- fatal ("%s: not a COFF file", prog_name);
-
- /* find and read loader section */
- if (ldnshread (ldptr, _LOADER, &ldsh))
- {
- LDHDR ldh;
- char *impbuf;
- int entry;
-
- FSEEK (ldptr, ldsh.s_scnptr, BEGINNING);
- FREAD (&ldh, sizeof (ldh), 1, ldptr);
- /* read import library list */
- impbuf = alloca (ldh.l_istlen);
- FSEEK (ldptr, ldh.l_impoff + ldsh.s_scnptr, BEGINNING);
- FREAD (impbuf, ldh.l_istlen, 1, ldptr);
+ char *p;
- if (debug)
- fprintf (stderr, "LIBPATH=%s\n", impbuf);
- prefix_from_string (impbuf, &libpath);
+ /* If we do not build a shared object then import list should not be used. */
+ if (! shared_obj) return 0;
- /* skip LIBPATH and empty base and member fields */
- impbuf += strlen (impbuf) + 3;
- for (entry = 1; entry < ldh.l_nimpid; ++entry)
- {
- char *impath = impbuf;
- char *implib = impath + strlen (impath) + 1;
- char *impmem = implib + strlen (implib) + 1;
- char *soname = NULL;
- char *trial;
- int pathlen;
- LDFILE *libptr = NULL;
- struct prefix_list *pl;
- ARCHDR ah;
-
- impbuf = impmem + strlen (impmem) + 1;
- if (debug)
- fprintf (stderr, "PATH+BASE=%s%s\n", impath, implib);
- /* Skip AIX kernel exports */
- if (*impath == '/' && *(impath+1) == '\0'
- && strcmp (implib, "unix") == 0)
- continue;
- pathlen = strlen (impath);
- trial = alloca (MAX (pathlen + 1, libpath.max_len)
- + strlen (implib) + 1);
- if (*impath)
- {
- strcpy (trial, impath);
- if (impath[pathlen - 1] != '/')
- trial[pathlen++] = '/';
- strcpy (trial + pathlen, implib);
- if (access (trial, R_OK) == 0)
- soname = trial;
- }
- else
- for (pl = libpath.plist; pl; pl = pl->next)
- {
- strcpy (trial, pl->prefix);
- strcat (trial, implib);
- if (access (trial, R_OK) == 0)
- {
- soname = trial;
- break;
- }
- }
+ /* 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;
+}
- if (! soname)
- fatal ("%s: library not found", implib);
- if (debug)
- if (*impmem)
- fprintf (stderr, "%s (%s)\n", soname, impmem);
- else
- fprintf (stderr, "%s\n", soname);
+/* Given a library name without "lib" prefix, this function
+ returns a full library name including a path. */
+static char *
+resolve_lib_name (name)
+ char *name;
+{
+ char *lib_buf;
+ int i, j, l = 0;
+
+ for (i = 0; libpaths[i]; i++)
+ if (libpaths[i]->max_len > l)
+ l = libpaths[i]->max_len;
+
+ lib_buf = xmalloc (l + strlen(name) + 10);
- do
+ for (i = 0; libpaths[i]; i++)
+ {
+ struct prefix_list *list = libpaths[i]->plist;
+ for (; list; list = list->next)
+ {
+ for (j = 0; libexts[j]; j++)
{
- /* scan imported shared objects for GCC GLOBAL ctors */
- short type;
- if ((libptr = ldopen (soname, libptr)) == NULL)
- fatal ("%s: can't open import library", soname);
- if (TYPE (libptr) == ARTYPE)
- {
- LDFILE *memptr;
- if (! *impmem)
- fatal ("%s: no archive member specified", soname);
- ldahread (libptr, &ah);
- if (strcmp (ah.ar_name, impmem))
- continue;
- }
- type = HEADER (libptr).f_magic;
- if (HEADER (libptr).f_flags & F_SHROBJ)
+ /* The following lines are needed because path_prefix list
+ may contain directories both with trailing '/' and
+ without it. */
+ 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);
+ if (file_exists (lib_buf))
{
- SCNHDR soldsh;
- LDHDR soldh;
- long symcnt, i;
- char *ldstrings;
- LDSYM *lsyms;
- if (!ldnshread (libptr, _LOADER, &soldsh))
- fatal ("%s: not an import library", soname);
- FSEEK (libptr, soldsh.s_scnptr, BEGINNING);
- if (FREAD (&soldh, sizeof (soldh), 1, libptr) != 1)
- fatal ("%s: can't read loader section", soname);
- /*fprintf (stderr, "\tscanning %s\n", soname);*/
- symcnt = soldh.l_nsyms;
- lsyms = (LDSYM*) alloca (symcnt * sizeof (*lsyms));
- symcnt = FREAD (lsyms, sizeof (*lsyms), symcnt, libptr);
- ldstrings = alloca (soldh.l_stlen);
- FSEEK (libptr, soldsh.s_scnptr+soldh.l_stoff, BEGINNING);
- FREAD (ldstrings, soldh.l_stlen, 1, libptr);
- for (i = 0; i < symcnt; ++i)
- {
- LDSYM *l = lsyms + i;
- if (LDR_EXPORT (*l))
- {
- char *expname = 0;
- if (l->l_zeroes)
- expname = l->l_name;
- else if (l->l_offset < soldh.l_stlen)
- expname = ldstrings + l->l_offset;
- switch (is_ctor_dtor (expname))
- {
- case 3:
- if (debug)
- fprintf (stderr, "\t%s\n", expname);
- add_to_list (&constructors, expname);
- break;
-
- case 4:
- add_to_list (&destructors, expname);
- break;
-
- default: /* not a constructor or destructor */
- continue;
- }
- }
- }
+if (debug) fprintf (stderr, "found: %s\n", lib_buf);
+ return (lib_buf);
}
- else
- fprintf (stderr, "%s: type = %04X flags = %04X\n",
- ah.ar_name, type, HEADER (libptr).f_flags);
}
- while (ldclose (libptr) == FAILURE);
- /* printf (stderr, "closed %s\n", soname); */
}
}
+ if (debug)
+ fprintf (stderr, "not found\n");
+ else
+ fatal ("Library lib%s not found", name);
+ return (NULL);
+}
+
+/* Array of standard AIX libraries which should not
+ be scanned for ctors/dtors. */
+static char* aix_std_libs[] = {
+ "/unix",
+ "/lib/libc.a",
+ "/lib/libc_r.a",
+ "/usr/lib/libc.a",
+ "/usr/lib/libc_r.a",
+ "/usr/lib/threads/libc.a",
+ "/usr/ccs/lib/libc.a",
+ "/usr/ccs/lib/libc_r.a",
+ NULL
+};
+
+/* This function checks the filename and returns 1
+ if this name matches the location of a standard AIX library. */
+static int
+ignore_library (name)
+ char *name;
+{
+ char **p = &aix_std_libs[0];
+ while (*p++ != NULL)
+ if (! strcmp (name, *p)) return 1;
+ return 0;
}
-#endif /* XCOFF_SCAN_LIBS */
+
+#endif
#endif /* OBJECT_FORMAT_COFF */
@@ -2787,7 +3020,7 @@ extern int encode_mach_o_hdr ();
static void add_func_table PROTO((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 print_load_command PROTO((load_union_t *, size_t, int));
static void bad_header PROTO((int));
static struct file_info *read_file PROTO((char *, int, int));
static void end_file PROTO((struct file_info *));
@@ -2826,7 +3059,7 @@ scan_prog_file (prog_name, which_pass)
prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
if (prog_fd < 0)
- fatal_perror ("can't read %s", prog_name);
+ fatal_perror ("cannot read %s", prog_name);
obj_file = read_file (prog_name, prog_fd, rw);
obj = obj_file->start;
@@ -2930,10 +3163,10 @@ scan_prog_file (prog_name, which_pass)
continue;
str_sect = load_array[load_hdr->sym.symc_strings_section].section;
- if (str_sect == (char *)0)
+ if (str_sect == (char *) 0)
fatal ("string section missing");
- if (load_cmd->section == (char *)0)
+ if (load_cmd->section == (char *) 0)
fatal ("section pointer missing");
num_syms = load_hdr->sym.symc_nentries;
@@ -2998,11 +3231,11 @@ scan_prog_file (prog_name, which_pass)
fatal ("no cmd_strings found");
/* Add __main to initializer list.
- If we are building a program instead of a shared library, don't
+ If we are building a program instead of a shared library, do not
do anything, since in the current version, you cannot do mallocs
and such in the constructors. */
- if (main_sym != (symbol_info_t *)0
+ if (main_sym != (symbol_info_t *) 0
&& ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
@@ -3057,7 +3290,7 @@ scan_prog_file (prog_name, which_pass)
if (debug)
print_load_command (load_hdr, offset, i);
- bcopy ((char *)load_hdr, (char *)(obj + offset), size);
+ bcopy ((char *) load_hdr, (char *) (obj + offset), size);
offset += size;
}
}
@@ -3096,7 +3329,7 @@ add_func_table (hdr_p, load_array, sym, type)
load_cmd = &load_array[load_index];
load_cmd->load = ptr;
- load_cmd->section = (char *)0;
+ load_cmd->section = (char *) 0;
/* Fill in func table load command. */
ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
@@ -3205,7 +3438,7 @@ print_load_command (load_hdr, offset, number)
int number;
{
mo_long_t type = load_hdr->hdr.ldci_cmd_type;
- char *type_str = (char *)0;
+ char *type_str = (char *) 0;
switch (type)
{
@@ -3230,7 +3463,7 @@ print_load_command (load_hdr, offset, number)
(long) load_hdr->hdr.ldci_section_off,
(long) load_hdr->hdr.ldci_section_len);
- if (type_str == (char *)0)
+ if (type_str == (char *) 0)
fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
else if (type != LDC_REGION)
@@ -3269,7 +3502,7 @@ static void
bad_header (status)
int status;
{
- char *msg = (char *)0;
+ char *msg = (char *) 0;
switch (status)
{
@@ -3281,7 +3514,7 @@ bad_header (status)
case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
}
- if (msg == (char *)0)
+ if (msg == (char *) 0)
fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
else
fatal ("%s", msg);
@@ -3319,14 +3552,14 @@ read_file (name, fd, rw)
page_size = sysconf (_SC_PAGE_SIZE);
p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
- p->start = mmap ((caddr_t)0,
+ p->start = mmap ((caddr_t) 0,
(rw) ? p->rounded_size : p->size,
(rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
MAP_FILE | MAP_VARIABLE | MAP_SHARED,
fd,
0L);
- if (p->start != (char *)0 && p->start != (char *)-1)
+ if (p->start != (char *) 0 && p->start != (char *) -1)
p->use_mmap = 1;
else
OpenPOWER on IntegriCloud