summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/collect2.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/collect2.c')
-rw-r--r--contrib/gcc/collect2.c567
1 files changed, 364 insertions, 203 deletions
diff --git a/contrib/gcc/collect2.c b/contrib/gcc/collect2.c
index 4fcbe73..121ad39 100644
--- a/contrib/gcc/collect2.c
+++ b/contrib/gcc/collect2.c
@@ -1,6 +1,6 @@
/* 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.
+ Copyright (C) 1992, 93-98, 1999 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).
@@ -28,38 +28,31 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include <signal.h>
-#include <sys/stat.h>
+
+#ifdef vfork /* Autoconf may define this to fork for us. */
+# define VFORK_STRING "fork"
+#else
+# define VFORK_STRING "vfork"
+#endif
+#ifdef HAVE_VFORK_H
+#include <vfork.h>
+#endif
+#ifdef VMS
+#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
+ lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
+#endif /* VMS */
#define COLLECT
+#include "collect2.h"
#include "demangle.h"
#include "obstack.h"
-#include "gansidecl.h"
-#ifdef __CYGWIN32__
-#include <process.h>
-#endif
+#include "intl.h"
/* Obstack allocation and deallocation routines. */
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-#ifdef USG
-#define vfork fork
-#endif
-
-#ifndef WIFSIGNALED
-#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
-#endif
-#ifndef WTERMSIG
-#define WTERMSIG(S) ((S) & 0x7f)
-#endif
-#ifndef WIFEXITED
-#define WIFEXITED(S) (((S) & 0xff) == 0)
-#endif
-#ifndef WEXITSTATUS
-#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
-#endif
-
extern char *make_temp_file PROTO ((char *));
/* On certain systems, we have code that works by scanning the object file
@@ -137,7 +130,7 @@ extern char *make_temp_file PROTO ((char *));
/* Default flags to pass to nm. */
#ifndef NM_FLAGS
-#define NM_FLAGS "-p"
+#define NM_FLAGS "-n"
#endif
#endif /* OBJECT_FORMAT_NONE */
@@ -151,6 +144,9 @@ extern char *make_temp_file PROTO ((char *));
#define SYMBOL__MAIN __main
#endif
+/* This must match tree.h. */
+#define DEFAULT_INIT_PRIORITY 65535
+
#if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
#define SCAN_LIBRARIES
#endif
@@ -186,11 +182,6 @@ enum pass {
PASS_SECOND /* with constructors linked in */
};
-#ifndef NO_SYS_SIGLIST
-#ifndef SYS_SIGLIST_DECLARED
-extern char *sys_siglist[];
-#endif
-#endif
extern char *version_string;
int vflag; /* true if -v */
@@ -234,14 +225,16 @@ struct obstack temporary_obstack;
struct obstack permanent_obstack;
char * temporary_firstobj;
+/* Holds the return value of pexecute. */
+int pexecute_pid;
+
/* Defined in the automatically-generated underscore.c. */
extern int prepends_underscore;
-extern char *mktemp ();
extern FILE *fdopen ();
-#ifndef GET_ENVIRONMENT
-#define GET_ENVIRONMENT(ENV_VALUE,ENV_NAME) ENV_VALUE = getenv (ENV_NAME)
+#ifndef GET_ENV_PATH_LIST
+#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
#endif
/* Structure to hold all the directories in which to search for files to
@@ -270,7 +263,13 @@ static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
static char *libexts[3] = {"a", "so", NULL}; /* possible library extentions */
#endif
+void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
+void fatal PVPROTO((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fatal_perror PVPROTO((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
static char *my_strerror PROTO((int));
+static const char *my_strsignal PROTO((int));
static void handler PROTO((int));
static int is_ctor_dtor PROTO((char *));
static char *find_a_file PROTO((struct path_prefix *, char *));
@@ -281,6 +280,8 @@ static void do_wait PROTO((char *));
static void fork_execute PROTO((char *, char **));
static void maybe_unlink PROTO((char *));
static void add_to_list PROTO((struct head *, char *));
+static int extract_init_priority PROTO((char *));
+static void sort_ids PROTO((struct head *));
static void write_list PROTO((FILE *, char *, struct id *));
#ifdef COLLECT_EXPORT_LIST
static void dump_list PROTO((FILE *, char *, struct id *));
@@ -302,10 +303,6 @@ 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 ();
-
#ifdef NO_DUP2
int
@@ -339,17 +336,38 @@ my_strerror (e)
#else
- static char buffer[30];
if (!e)
return "";
if (e > 0 && e < sys_nerr)
return sys_errlist[e];
- sprintf (buffer, "Unknown error %d", e);
- return buffer;
+ return "errno = ?";
#endif
}
+
+static const char *
+my_strsignal (s)
+ int s;
+{
+#ifdef HAVE_STRSIGNAL
+ return strsignal (s);
+#else
+ if (s >= 0 && s < NSIG)
+ {
+# ifdef NO_SYS_SIGLIST
+ static char buffer[30];
+
+ sprintf (buffer, "Unknown signal %d", s);
+ return buffer;
+# else
+ return sys_siglist[s];
+# endif
+ }
+ else
+ return NULL;
+#endif /* HAVE_STRSIGNAL */
+}
/* Delete tempfiles and exit function. */
@@ -384,41 +402,94 @@ collect_exit (status)
}
+/* Notify user of a non-error. */
+void
+notice VPROTO((char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, char *);
+#endif
+
+ vfprintf (stderr, _(msgid), ap);
+ va_end (ap);
+}
+
/* Die when sys call fails. */
void
-fatal_perror (string, arg1, arg2, arg3)
- char *string, *arg1, *arg2, *arg3;
+fatal_perror VPROTO((const char * msgid, ...))
{
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
+#endif
int e = errno;
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
+#endif
fprintf (stderr, "collect2: ");
- fprintf (stderr, string, arg1, arg2, arg3);
+ vfprintf (stderr, _(msgid), ap);
fprintf (stderr, ": %s\n", my_strerror (e));
+ va_end (ap);
+
collect_exit (FATAL_EXIT_CODE);
}
/* Just die. */
void
-fatal (string, arg1, arg2, arg3)
- char *string, *arg1, *arg2, *arg3;
+fatal VPROTO((const char * msgid, ...))
{
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
+#endif
+
fprintf (stderr, "collect2: ");
- fprintf (stderr, string, arg1, arg2, arg3);
+ vfprintf (stderr, _(msgid), ap);
fprintf (stderr, "\n");
+ va_end (ap);
+
collect_exit (FATAL_EXIT_CODE);
}
/* Write error message. */
void
-error (string, arg1, arg2, arg3, arg4)
- char *string, *arg1, *arg2, *arg3, *arg4;
+error VPROTO((const char * msgid, ...))
{
+#ifndef ANSI_PROTOTYPES
+ const char * msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
+#endif
+
fprintf (stderr, "collect2: ");
- fprintf (stderr, string, arg1, arg2, arg3, arg4);
+ vfprintf (stderr, _(msgid), ap);
fprintf (stderr, "\n");
+ va_end(ap);
}
/* In case obstack is linked in, and abort is defined to fancy_abort,
@@ -429,7 +500,6 @@ fancy_abort ()
{
fatal ("internal error");
}
-
static void
handler (signo)
@@ -457,39 +527,39 @@ handler (signo)
}
-char *
+PTR
xcalloc (size1, size2)
- int size1, size2;
+ size_t size1, size2;
{
- char *ptr = (char *) calloc (size1, size2);
- if (ptr)
- return ptr;
-
- fatal ("out of memory");
- return (char *) 0;
+ PTR ptr = (PTR) calloc (size1, size2);
+ if (!ptr)
+ fatal ("out of memory");
+ return ptr;
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- char *ptr = (char *) malloc (size);
- if (ptr)
- return ptr;
-
- fatal ("out of memory");
- return (char *) 0;
+ PTR ptr = (PTR) malloc (size);
+ if (!ptr)
+ fatal ("out of memory");
+ return ptr;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- register char *value = (char *) realloc (ptr, size);
- if (value == 0)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (ptr == 0)
fatal ("virtual memory exhausted");
- return value;
+ return ptr;
}
int
@@ -502,13 +572,12 @@ file_exists (name)
/* Make a copy of a string INPUT with size SIZE. */
char *
-savestring (input, size)
- char *input;
- int size;
+xstrdup (input)
+ const char *input;
{
- char *output = (char *) xmalloc (size + 1);
- bcopy (input, output, size);
- output[size] = 0;
+ register size_t len = strlen (input) + 1;
+ register char *output = xmalloc (len);
+ memcpy (output, input, len);
return output;
}
@@ -754,9 +823,8 @@ find_a_file (pprefix, name)
/* Determine the filename to execute (special case for absolute paths). */
if (*name == '/'
-#ifdef DIR_SEPARATOR
- || (DIR_SEPARATOR == '\\' && name[1] == ':'
- && (name[2] == DIR_SEPARATOR || name[2] == '/'))
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ || (*name && name[1] == ':')
#endif
)
{
@@ -770,6 +838,16 @@ find_a_file (pprefix, name)
return temp;
}
+#ifdef EXECUTABLE_SUFFIX
+ /* Some systems have a suffix for executable files.
+ So try appending that. */
+ strcpy (temp, name);
+ strcat (temp, EXECUTABLE_SUFFIX);
+
+ if (access (temp, X_OK) == 0)
+ return temp;
+#endif
+
if (debug)
fprintf (stderr, " - failed to locate using absolute path\n");
}
@@ -825,7 +903,7 @@ add_prefix (pprefix, prefix)
pprefix->max_len = len;
pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
- pl->prefix = savestring (prefix, len);
+ pl->prefix = xstrdup (prefix);
if (*prev)
pl->next = *prev;
@@ -843,7 +921,7 @@ prefix_from_env (env, pprefix)
struct path_prefix *pprefix;
{
char *p;
- GET_ENVIRONMENT (p, env);
+ GET_ENV_PATH_LIST (p, env);
if (p)
prefix_from_string (p, pprefix);
@@ -924,15 +1002,33 @@ main (argc, argv)
char *p;
char **c_argv;
char **c_ptr;
- char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+3);
- char **ld1 = ld1_argv;
- char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+6);
- char **ld2 = ld2_argv;
- char **object_lst = (char **) xcalloc (sizeof (char *), argc);
- char **object = object_lst;
+ char **ld1_argv;
+ char **ld1;
+ char **ld2_argv;
+ char **ld2;
+ char **object_lst;
+ char **object;
int first_file;
int num_c_args = argc+9;
+#if defined (COLLECT2_HOST_INITIALIZATION)
+ /* Perform system dependant initialization, if neccessary. */
+ COLLECT2_HOST_INITIALIZATION;
+#endif
+
+#ifdef HAVE_LC_MESSAGES
+ setlocale (LC_MESSAGES, "");
+#endif
+ (void) bindtextdomain (PACKAGE, localedir);
+ (void) textdomain (PACKAGE);
+
+ /* Do not invoke xcalloc before this point, since locale needs to be
+ set first, in case a diagnostic is issued. */
+
+ ld1 = ld1_argv = (char **) xcalloc (sizeof (char *), argc+3);
+ ld2 = ld2_argv = (char **) xcalloc (sizeof (char *), argc+6);
+ object = object_lst = (char **) xcalloc (sizeof (char *), argc);
+
#ifdef DEBUG
debug = 1;
#endif
@@ -1056,6 +1152,12 @@ main (argc, argv)
/* Try to discover a valid linker/nm/strip to use. */
/* Maybe we know the right file to use (if not cross). */
+ ld_file_name = 0;
+#ifdef DEFAULT_LINKER
+ if (access (DEFAULT_LINKER, X_OK) == 0)
+ ld_file_name = DEFAULT_LINKER;
+ if (ld_file_name == 0)
+#endif
#ifdef REAL_LD_FILE_NAME
ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
if (ld_file_name == 0)
@@ -1164,6 +1266,8 @@ main (argc, argv)
char *q = extract_string (&p);
if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
*c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
+ if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
+ *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0)
shared_obj = 1;
}
@@ -1195,7 +1299,7 @@ main (argc, argv)
case 'b':
if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
export_flag = 1;
- if (arg[2] == '6' && arg[3] == '4')
+ else if (arg[2] == '6' && arg[3] == '4')
aix64_flag = 1;
break;
#endif
@@ -1342,16 +1446,16 @@ main (argc, argv)
*ld2++ = buf2;
exportf = fopen (export_file, "w");
if (exportf == (FILE *) 0)
- fatal_perror ("%s", export_file);
+ fatal_perror ("fopen %s", export_file);
write_export_file (exportf);
if (fclose (exportf))
- fatal_perror ("closing %s", export_file);
+ fatal_perror ("fclose %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);
+ fatal_perror ("fclose %s", import_file);
}
#endif
@@ -1360,7 +1464,7 @@ main (argc, argv)
if (vflag)
{
- fprintf (stderr, "collect2 version %s", version_string);
+ notice ("collect2 version %s", version_string);
#ifdef TARGET_VERSION
TARGET_VERSION;
#endif
@@ -1449,8 +1553,9 @@ main (argc, argv)
if (debug)
{
- fprintf (stderr, "%d constructor(s) found\n", constructors.number);
- fprintf (stderr, "%d destructor(s) found\n", destructors.number);
+ notice ("%d constructor(s) found\n", constructors.number);
+ notice ("%d destructor(s) found\n", destructors.number);
+ notice ("%d frame table(s) found\n", frame_tables.number);
}
if (constructors.number == 0 && destructors.number == 0
@@ -1486,15 +1591,19 @@ main (argc, argv)
return 0;
}
+ /* Sort ctor and dtor lists by priority. */
+ sort_ids (&constructors);
+ sort_ids (&destructors);
+
maybe_unlink(output_file);
outf = fopen (c_file, "w");
if (outf == (FILE *) 0)
- fatal_perror ("%s", c_file);
+ fatal_perror ("fopen %s", c_file);
write_c_file (outf, c_file);
if (fclose (outf))
- fatal_perror ("closing %s", c_file);
+ fatal_perror ("fclose %s", c_file);
/* Tell the linker that we have initializer and finalizer functions. */
#ifdef LD_INIT_SWITCH
@@ -1514,10 +1623,10 @@ main (argc, argv)
add_to_list (&exports, "_GLOBAL__DD");
exportf = fopen (export_file, "w");
if (exportf == (FILE *) 0)
- fatal_perror ("%s", export_file);
+ fatal_perror ("fopen %s", export_file);
write_export_file (exportf);
if (fclose (exportf))
- fatal_perror ("closing %s", export_file);
+ fatal_perror ("fclose %s", export_file);
}
#endif
@@ -1570,25 +1679,18 @@ collect_wait (prog)
{
int status;
- wait (&status);
+ pwait (pexecute_pid, &status, 0);
if (status)
{
if (WIFSIGNALED (status))
{
int sig = WTERMSIG (status);
-#ifdef NO_SYS_SIGLIST
- error ("%s terminated with signal %d %s",
+ error ((status & 0200
+ ? "%s terminated with signal %d [%s]"
+ : "%s terminated with signal %d [%s], core dumped"),
prog,
sig,
- (status & 0200) ? ", core dumped" : "");
-#else
- error ("%s terminated with signal %d [%s]%s",
- prog,
- sig,
- sys_siglist[sig],
- (status & 0200) ? ", core dumped" : "");
-#endif
-
+ my_strsignal(sig));
collect_exit (FATAL_EXIT_CODE);
}
@@ -1611,7 +1713,7 @@ do_wait (prog)
}
-/* Fork and execute a program, and wait for the reply. */
+/* Execute a program, and wait for the reply. */
void
collect_execute (prog, argv, redir)
@@ -1619,7 +1721,11 @@ collect_execute (prog, argv, redir)
char **argv;
char *redir;
{
- int pid;
+ char *errmsg_fmt;
+ char *errmsg_arg;
+ int redir_handle = -1;
+ int stdout_save = -1;
+ int stderr_save = -1;
if (vflag || debug)
{
@@ -1629,7 +1735,7 @@ collect_execute (prog, argv, redir)
if (argv[0])
fprintf (stderr, "%s", argv[0]);
else
- fprintf (stderr, "[cannot find %s]", prog);
+ notice ("[cannot find %s]", prog);
for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
fprintf (stderr, " %s", str);
@@ -1646,36 +1752,41 @@ collect_execute (prog, argv, redir)
if (argv[0] == 0)
fatal ("cannot find `%s'", prog);
-#ifndef __CYGWIN32__
- pid = vfork ();
- if (pid == -1)
+ if (redir)
{
-#ifdef vfork
- fatal_perror ("fork");
-#else
- fatal_perror ("vfork");
-#endif
+ /* Open response file. */
+ redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
+
+ /* Duplicate the stdout and stderr file handles
+ so they can be restored later. */
+ stdout_save = dup (STDOUT_FILENO);
+ if (stdout_save == -1)
+ fatal_perror ("redirecting stdout: %s", redir);
+ stderr_save = dup (STDERR_FILENO);
+ if (stderr_save == -1)
+ fatal_perror ("redirecting stdout: %s", redir);
+
+ /* Redirect stdout & stderr to our response file. */
+ dup2 (redir_handle, STDOUT_FILENO);
+ dup2 (redir_handle, STDERR_FILENO);
}
- if (pid == 0) /* child context */
+ pexecute_pid = pexecute (argv[0], argv, argv[0], NULL,
+ &errmsg_fmt, &errmsg_arg,
+ (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH));
+
+ if (redir)
{
- if (redir)
- {
- unlink (redir);
- if (freopen (redir, "a", stdout) == NULL)
- fatal_perror ("redirecting stdout: %s", redir);
- if (freopen (redir, "a", stderr) == NULL)
- fatal_perror ("redirecting stderr: %s", redir);
- }
+ /* Restore stdout and stderr to their previous settings. */
+ dup2 (stdout_save, STDOUT_FILENO);
+ dup2 (stderr_save, STDERR_FILENO);
- execvp (argv[0], argv);
- fatal_perror ("executing %s", prog);
+ /* Close reponse file. */
+ close (redir_handle);
}
-#else
- pid = _spawnvp (_P_NOWAIT, argv[0], argv);
- if (pid == -1)
- fatal ("spawnvp failed");
-#endif
+
+ if (pexecute_pid == -1)
+ fatal_perror (errmsg_fmt, errmsg_arg);
}
static void
@@ -1696,10 +1807,12 @@ maybe_unlink (file)
if (!debug)
unlink (file);
else
- fprintf (stderr, "[Leaving %s]\n", file);
+ notice ("[Leaving %s]\n", file);
}
+static long sequence_number = 0;
+
/* Add a name to a linked list. */
static void
@@ -1710,7 +1823,6 @@ add_to_list (head_ptr, name)
struct id *newid
= (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
struct id *p;
- static long sequence_number = 0;
strcpy (newid->name, name);
if (head_ptr->first)
@@ -1735,6 +1847,67 @@ add_to_list (head_ptr, name)
head_ptr->number++;
}
+/* Grab the init priority number from an init function name that
+ looks like "_GLOBAL_.I.12345.foo". */
+
+static int
+extract_init_priority (name)
+ char *name;
+{
+ int pos = 0, pri;
+
+ while (name[pos] == '_')
+ ++pos;
+ pos += 10; /* strlen ("GLOBAL__X_") */
+
+ /* Extract init_p number from ctor/dtor name. */
+ pri = atoi (name + pos);
+ return pri ? pri : DEFAULT_INIT_PRIORITY;
+}
+
+/* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
+ ctors will be run from right to left, dtors from left to right. */
+
+static void
+sort_ids (head_ptr)
+ struct head *head_ptr;
+{
+ /* id holds the current element to insert. id_next holds the next
+ element to insert. id_ptr iterates through the already sorted elements
+ looking for the place to insert id. */
+ struct id *id, *id_next, **id_ptr;
+
+ id = head_ptr->first;
+
+ /* We don't have any sorted elements yet. */
+ head_ptr->first = NULL;
+
+ for (; id; id = id_next)
+ {
+ id_next = id->next;
+ id->sequence = extract_init_priority (id->name);
+
+ for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
+ if (*id_ptr == NULL
+ /* If the sequence numbers are the same, we put the id from the
+ file later on the command line later in the list. */
+ || id->sequence > (*id_ptr)->sequence
+ /* Hack: do lexical compare, too.
+ || (id->sequence == (*id_ptr)->sequence
+ && strcmp (id->name, (*id_ptr)->name) > 0) */
+ )
+ {
+ id->next = *id_ptr;
+ *id_ptr = id;
+ break;
+ }
+ }
+
+ /* Now set the sequence numbers properly so write_c_file works. */
+ for (id = head_ptr->first; id; id = id->next)
+ id->sequence = ++sequence_number;
+}
+
/* Write: `prefix', the names on list LIST, `suffix'. */
static void
@@ -1853,11 +2026,11 @@ 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 ((unsigned char)*q))
*q = '_';
if (debug)
- fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n",
- output_file, prefix);
+ 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);
@@ -2114,28 +2287,22 @@ scan_prog_file (prog_name, which_pass)
/* Spawn child nm on pipe */
pid = vfork ();
if (pid == -1)
- {
-#ifdef vfork
- fatal_perror ("fork");
-#else
- fatal_perror ("vfork");
-#endif
- }
+ fatal_perror (VFORK_STRING);
if (pid == 0) /* child context */
{
/* setup stdout */
if (dup2 (pipe_fd[1], 1) < 0)
- fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
+ fatal_perror ("dup2 %d 1", pipe_fd[1]);
if (close (pipe_fd[0]) < 0)
- fatal_perror ("close (%d)", pipe_fd[0]);
+ fatal_perror ("close %d", pipe_fd[0]);
if (close (pipe_fd[1]) < 0)
- fatal_perror ("close (%d)", pipe_fd[1]);
+ fatal_perror ("close %d", pipe_fd[1]);
execv (nm_file_name, nm_argv);
- fatal_perror ("executing %s", nm_file_name);
+ fatal_perror ("execvp %s", nm_file_name);
}
/* Parent context from here on. */
@@ -2145,7 +2312,7 @@ scan_prog_file (prog_name, which_pass)
#endif
if (close (pipe_fd[1]) < 0)
- fatal_perror ("close (%d)", pipe_fd[1]);
+ fatal_perror ("close %d", pipe_fd[1]);
if (debug)
fprintf (stderr, "\nnm output with constructors/destructors.\n");
@@ -2206,6 +2373,7 @@ scan_prog_file (prog_name, which_pass)
case 5:
if (which_pass != PASS_LIB)
add_to_list (&frame_tables, name);
+ break;
default: /* not a constructor or destructor */
continue;
@@ -2219,7 +2387,7 @@ scan_prog_file (prog_name, which_pass)
fprintf (stderr, "\n");
if (fclose (inf) != 0)
- fatal_perror ("fclose of pipe");
+ fatal_perror ("fclose");
do_wait (nm_file_name);
@@ -2421,7 +2589,7 @@ locatelib (name)
if (*pp == 0)
{
if (debug)
- fprintf (stderr, "not found\n");
+ notice ("not found\n");
else
fatal ("dynamic dependency %s not found", name);
}
@@ -2465,7 +2633,7 @@ scan_libraries (prog_name)
}
if (debug)
- fprintf (stderr, "dynamic dependencies.\n");
+ notice ("dynamic dependencies.\n");
ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
for (lo = (struct link_object *) ld_2->ld_need; lo;
@@ -2556,28 +2724,22 @@ scan_libraries (prog_name)
/* Spawn child ldd on pipe */
pid = vfork ();
if (pid == -1)
- {
-#ifdef vfork
- fatal_perror ("fork");
-#else
- fatal_perror ("vfork");
-#endif
- }
+ fatal_perror (VFORK_STRING);
if (pid == 0) /* child context */
{
/* setup stdout */
if (dup2 (pipe_fd[1], 1) < 0)
- fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
+ fatal_perror ("dup2 %d 1", pipe_fd[1]);
if (close (pipe_fd[0]) < 0)
- fatal_perror ("close (%d)", pipe_fd[0]);
+ fatal_perror ("close %d", pipe_fd[0]);
if (close (pipe_fd[1]) < 0)
- fatal_perror ("close (%d)", pipe_fd[1]);
+ fatal_perror ("close %d", pipe_fd[1]);
execv (ldd_file_name, ldd_argv);
- fatal_perror ("executing %s", ldd_file_name);
+ fatal_perror ("execv %s", ldd_file_name);
}
/* Parent context from here on. */
@@ -2587,10 +2749,10 @@ scan_libraries (prog_name)
#endif
if (close (pipe_fd[1]) < 0)
- fatal_perror ("close (%d)", pipe_fd[1]);
+ fatal_perror ("close %d", pipe_fd[1]);
if (debug)
- fprintf (stderr, "\nldd output with constructors/destructors.\n");
+ notice ("\nldd output with constructors/destructors.\n");
/* Read each line of ldd output. */
while (fgets (buf, sizeof buf, inf) != (char *) 0)
@@ -2626,7 +2788,7 @@ scan_libraries (prog_name)
fprintf (stderr, "\n");
if (fclose (inf) != 0)
- fatal_perror ("fclose of pipe");
+ fatal_perror ("fclose");
do_wait (ldd_file_name);
@@ -2656,7 +2818,7 @@ scan_libraries (prog_name)
#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).sc == scText)
+# 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)
@@ -2796,6 +2958,11 @@ scan_prog_file (prog_name, which_pass)
break;
#endif
+ case 5:
+ if (! is_shared)
+ add_to_list (&frame_tables, name);
+ break;
+
default: /* not a constructor or destructor */
#ifdef COLLECT_EXPORT_LIST
/* If we are building a shared object on AIX we need
@@ -3059,7 +3226,7 @@ scan_prog_file (prog_name, which_pass)
prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
if (prog_fd < 0)
- fatal_perror ("cannot read %s", prog_name);
+ fatal_perror ("open %s", prog_name);
obj_file = read_file (prog_name, prog_fd, rw);
obj = obj_file->start;
@@ -3155,8 +3322,8 @@ scan_prog_file (prog_name, which_pass)
case SYMC_STABS: kind = "stabs"; break;
}
- fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
- symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
+ notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
+ symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
}
if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
@@ -3240,15 +3407,15 @@ scan_prog_file (prog_name, which_pass)
add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
if (debug)
- fprintf (stderr, "\nUpdating header and load commands.\n\n");
+ notice ("\nUpdating header and load commands.\n\n");
hdr.moh_n_load_cmds++;
size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
/* Create new load command map. */
if (debug)
- fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
- (int)hdr.moh_n_load_cmds, (long)size);
+ notice ("load command map, %d cmds, new size %ld.\n",
+ (int) hdr.moh_n_load_cmds, (long) size);
load_map = (load_union_t *) xcalloc (1, size);
load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
@@ -3278,7 +3445,7 @@ scan_prog_file (prog_name, which_pass)
bad_header (status);
if (debug)
- fprintf (stderr, "writing load commands.\n\n");
+ notice ("writing load commands.\n\n");
/* Write load commands */
offset = hdr.moh_first_cmd_off;
@@ -3298,7 +3465,7 @@ scan_prog_file (prog_name, which_pass)
end_file (obj_file);
if (close (prog_fd))
- fatal_perror ("closing %s", prog_name);
+ fatal_perror ("close %s", prog_name);
if (debug)
fprintf (stderr, "\n");
@@ -3376,12 +3543,11 @@ add_func_table (hdr_p, load_array, sym, type)
}
if (debug)
- fprintf (stderr,
- "%s function, region %d, offset = %ld (0x%.8lx)\n",
- (type == FNTC_INITIALIZATION) ? "init" : "term",
- (int)ptr->func.fntc_entry_loc[i].adr_lcid,
- (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
- (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
+ notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
+ type == FNTC_INITIALIZATION ? "init" : "term",
+ (int) ptr->func.fntc_entry_loc[i].adr_lcid,
+ (long) ptr->func.fntc_entry_loc[i].adr_sctoff,
+ (long) ptr->func.fntc_entry_loc[i].adr_sctoff);
}
@@ -3502,22 +3668,17 @@ static void
bad_header (status)
int status;
{
- char *msg = (char *) 0;
-
switch (status)
{
- case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break;
- case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break;
- case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break;
- case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break;
- case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break;
- case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
+ case MO_ERROR_BAD_MAGIC: fatal ("bad magic number");
+ case MO_ERROR_BAD_HDR_VERS: fatal ("bad header version");
+ case MO_ERROR_BAD_RAW_HDR_VERS: fatal ("bad raw header version");
+ case MO_ERROR_BUF2SML: fatal ("raw header buffer too small");
+ case MO_ERROR_OLD_RAW_HDR_FILE: fatal ("old raw header file");
+ case MO_ERROR_UNSUPPORTED_VERS: fatal ("unsupported version");
+ default:
+ fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
}
-
- if (msg == (char *) 0)
- fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
- else
- fatal ("%s", msg);
}
@@ -3573,7 +3734,7 @@ read_file (name, fd, rw)
p->use_mmap = 0;
p->start = xmalloc (p->size);
if (lseek (fd, 0L, SEEK_SET) < 0)
- fatal_perror ("lseek to 0 on %s", name);
+ fatal_perror ("lseek %s 0", name);
len = read (fd, p->start, p->size);
if (len < 0)
@@ -3621,7 +3782,7 @@ end_file (ptr)
fprintf (stderr, "write %s\n", ptr->name);
if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
- fatal_perror ("lseek to 0 on %s", ptr->name);
+ fatal_perror ("lseek %s 0", ptr->name);
len = write (ptr->fd, ptr->start, ptr->size);
if (len < 0)
OpenPOWER on IntegriCloud