diff options
Diffstat (limited to 'contrib/gcc/collect2.c')
-rw-r--r-- | contrib/gcc/collect2.c | 567 |
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) |