summaryrefslogtreecommitdiff
path: root/gcc/collect2.c
diff options
context:
space:
mode:
authormerrill <merrill@138bc75d-0d04-0410-961f-82ee72b054a4>1995-05-04 21:25:31 +0000
committermerrill <merrill@138bc75d-0d04-0410-961f-82ee72b054a4>1995-05-04 21:25:31 +0000
commitd2f0b72425c391e3071fa7f77fc720c086a6c4aa (patch)
treed5cd65fb4395c72a796b852f8a232c7bca3a2253 /gcc/collect2.c
parentd4e7442d33f239504da5ce756ce19baabdc9a171 (diff)
downloadgcc-d2f0b72425c391e3071fa7f77fc720c086a6c4aa.tar.gz
Make collect demangle
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@9573 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/collect2.c')
-rw-r--r--gcc/collect2.c265
1 files changed, 195 insertions, 70 deletions
diff --git a/gcc/collect2.c b/gcc/collect2.c
index dc91a9428d0..065178b23e3 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -55,13 +55,16 @@ char *strerror();
#define COLLECT
#include "config.h"
+#include "demangle.h"
-#ifndef __STDC__
-#define generic char
-#define const
+#include "obstack.h"
-#else
-#define generic void
+/* 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
@@ -193,9 +196,15 @@ char *strerror();
#define SYMBOL__MAIN __main
#endif
-#if defined (LDD_SUFFIX) || defined (SUNOS4_SHARED_LIBRARIES)
+#if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
#define SCAN_LIBRARIES
#endif
+
+#ifdef USE_COLLECT2
+int do_collecting = 1;
+#else
+int do_collecting = 0;
+#endif
/* Linked lists of constructor and destructor names. */
@@ -228,11 +237,11 @@ extern char *sys_siglist[];
#endif
extern char *version_string;
-static int vflag; /* true if -v */
+int vflag; /* true if -v */
static int rflag; /* true if -r */
static int strip_flag; /* true if -s */
-static int debug; /* true if -debug */
+int debug; /* true if -debug */
static int shared_obj; /* true if -shared */
@@ -240,14 +249,23 @@ 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. */
+char *ldout; /* File for ld errors. */
static char *output_file; /* Output file for ld. */
static char *nm_file_name; /* pathname of nm */
static char *ldd_file_name; /* pathname of ldd (or equivalent) */
static char *strip_file_name; /* pathname of strip */
+char *c_file_name; /* pathname of gcc */
static struct head constructors; /* list of constructors found */
static struct head destructors; /* list of destructors found */
+struct obstack temporary_obstack;
+struct obstack permanent_obstack;
+char * temporary_firstobj;
+
+/* Defined in the automatically-generated underscore.c. */
+extern int prepends_underscore;
+
extern char *getenv ();
extern char *mktemp ();
extern FILE *fdopen ();
@@ -268,7 +286,9 @@ struct path_prefix
char *name; /* Name of this list (used in config stuff) */
};
-static void my_exit PROTO((int));
+void collect_exit PROTO((int));
+void collect_execute PROTO((char *, char **, char *));
+void dump_file PROTO((char *));
static void handler PROTO((int));
static int is_ctor_dtor PROTO((char *));
static void choose_temp_base PROTO((void));
@@ -286,11 +306,12 @@ static void write_c_file PROTO((FILE *, char *));
static void scan_prog_file PROTO((char *, enum pass));
static void scan_libraries PROTO((char *));
-generic *xcalloc ();
-generic *xmalloc ();
+char *xcalloc ();
+char *xmalloc ();
extern char *index ();
extern char *rindex ();
+extern void free ();
#ifdef NO_DUP2
int
@@ -338,8 +359,8 @@ my_strerror (e)
/* Delete tempfiles and exit function. */
-static void
-my_exit (status)
+void
+collect_exit (status)
int status;
{
if (c_file != 0 && c_file[0])
@@ -348,6 +369,12 @@ my_exit (status)
if (o_file != 0 && o_file[0])
maybe_unlink (o_file);
+ if (ldout != 0 && ldout[0])
+ {
+ dump_file (ldout);
+ maybe_unlink (ldout);
+ }
+
if (status != 0 && output_file != 0 && output_file[0])
maybe_unlink (output_file);
@@ -357,7 +384,7 @@ my_exit (status)
/* Die when sys call fails. */
-static void
+void
fatal_perror (string, arg1, arg2, arg3)
char *string, *arg1, *arg2, *arg3;
{
@@ -366,24 +393,24 @@ fatal_perror (string, arg1, arg2, arg3)
fprintf (stderr, "collect2: ");
fprintf (stderr, string, arg1, arg2, arg3);
fprintf (stderr, ": %s\n", my_strerror (e));
- my_exit (1);
+ collect_exit (1);
}
/* Just die. */
-static void
+void
fatal (string, arg1, arg2, arg3)
char *string, *arg1, *arg2, *arg3;
{
fprintf (stderr, "collect2: ");
fprintf (stderr, string, arg1, arg2, arg3);
fprintf (stderr, "\n");
- my_exit (1);
+ collect_exit (1);
}
/* Write error message. */
-static void
+void
error (string, arg1, arg2, arg3, arg4)
char *string, *arg1, *arg2, *arg3, *arg4;
{
@@ -412,33 +439,54 @@ handler (signo)
if (o_file != 0 && o_file[0])
maybe_unlink (o_file);
+ if (ldout != 0 && ldout[0])
+ maybe_unlink (ldout);
+
signal (signo, SIG_DFL);
kill (getpid (), signo);
}
-generic *
+char *
xcalloc (size1, size2)
int size1, size2;
{
- generic *ptr = (generic *) calloc (size1, size2);
+ char *ptr = (char *) calloc (size1, size2);
if (ptr)
return ptr;
fatal ("out of memory");
- return (generic *)0;
+ return (char *)0;
}
-generic *
+char *
xmalloc (size)
- int size;
+ unsigned size;
{
- generic *ptr = (generic *) malloc (size);
+ char *ptr = (char *) malloc (size);
if (ptr)
return ptr;
fatal ("out of memory");
- return (generic *)0;
+ return (char *)0;
+}
+
+char *
+xrealloc (ptr, size)
+ char *ptr;
+ unsigned size;
+{
+ register char *value = (char *) realloc (ptr, size);
+ if (value == 0)
+ fatal ("virtual memory exhausted");
+ return value;
+}
+
+int
+file_exists (name)
+ char *name;
+{
+ return access (name, R_OK) == 0;
}
/* Make a copy of a string INPUT with size SIZE. */
@@ -454,6 +502,63 @@ savestring (input, size)
return output;
}
+void
+dump_file (name)
+ char *name;
+{
+ FILE *stream = fopen (name, "r");
+ int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
+
+ if (stream == 0)
+ return;
+ while (1)
+ {
+ int c;
+ while (c = getc (stream),
+ c != EOF && (isalnum (c) || c == '_' || c == '$' || c == '.'))
+ obstack_1grow (&temporary_obstack, c);
+ if (obstack_object_size (&temporary_obstack) > 0)
+ {
+ char *word, *p, *result;
+ obstack_1grow (&temporary_obstack, '\0');
+ word = obstack_finish (&temporary_obstack);
+
+ if (*word == '.')
+ ++word, putc ('.', stderr);
+ p = word;
+ if (*p == '_' && prepends_underscore)
+ ++p;
+
+ if (no_demangle)
+ result = 0;
+ else
+ result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
+
+ if (result)
+ {
+ int diff;
+ fputs (result, stderr);
+
+ diff = strlen (word) - strlen (result);
+ while (diff > 0)
+ --diff, putc (' ', stderr);
+ while (diff < 0 && c == ' ')
+ ++diff, c = getc (stream);
+
+ free (result);
+ }
+ else
+ fputs (word, stderr);
+
+ fflush (stderr);
+ obstack_free (&temporary_obstack, temporary_firstobj);
+ }
+ if (c == EOF)
+ break;
+ putc (c, stderr);
+ }
+}
+
/* Decide whether the given symbol is:
a constructor (1), a destructor (2), or neither (0). */
@@ -799,10 +904,7 @@ main (argc, argv)
char *full_ld_suffix = ld_suffix;
char *real_ld_suffix = "real-ld";
char *full_real_ld_suffix = real_ld_suffix;
-#if 0
- char *gld_suffix = "gld";
- char *full_gld_suffix = gld_suffix;
-#endif
+ char *collect_ld_suffix = "collect-ld";
char *nm_suffix = "nm";
char *full_nm_suffix = nm_suffix;
char *gnm_suffix = "gnm";
@@ -818,7 +920,6 @@ main (argc, argv)
char *arg;
FILE *outf;
char *ld_file_name;
- char *c_file_name;
char *collect_name;
char *collect_names;
char *p;
@@ -840,6 +941,11 @@ main (argc, argv)
output_file = "a.out";
+ 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.
@@ -992,21 +1098,11 @@ main (argc, argv)
ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
if (ld_file_name == 0)
#endif
-#if 0
- /* Search the (target-specific) compiler dirs for `gld'. */
- ld_file_name = find_a_file (&cpath, gld_suffix);
- /* Search the ordinary system bin directories
- for `gld' (if native linking) or `TARGET-gld' (if cross). */
- if (ld_file_name == 0)
- ld_file_name = find_a_file (&path, full_gld_suffix);
-#else
- ld_file_name = 0;
-#endif
- /* Likewise for `real-ld'. */
+ /* Search the (target-specific) compiler dirs for ld'. */
+ ld_file_name = find_a_file (&cpath, real_ld_suffix);
+ /* Likewise for `collect-ld'. */
if (ld_file_name == 0)
- ld_file_name = find_a_file (&cpath, real_ld_suffix);
- if (ld_file_name == 0)
- ld_file_name = find_a_file (&path, full_real_ld_suffix);
+ ld_file_name = find_a_file (&cpath, collect_ld_suffix);
/* Search the compiler directories for `ld'. We have protection against
recursive calls in find_a_file. */
if (ld_file_name == 0)
@@ -1087,6 +1183,8 @@ main (argc, argv)
choose_temp_base ();
c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);
o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);
+ 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);
*c_ptr++ = c_file_name;
@@ -1144,7 +1242,7 @@ main (argc, argv)
break;
case 's':
- if (arg[2] == '\0')
+ 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
@@ -1206,7 +1304,7 @@ main (argc, argv)
}
*c_ptr++ = c_file;
- *c_ptr = *ld1 = *ld2 = (char *)0;
+ *object = *c_ptr = *ld1 = *ld2 = (char *)0;
if (vflag)
{
@@ -1260,17 +1358,22 @@ main (argc, argv)
fprintf (stderr, "\n");
}
- /* Load the program, searching all libraries.
- 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. */
+ /* Load the program, searching all libraries. */
- fork_execute ("ld", ld1_argv);
+ collect_execute ("ld", ld1_argv, ldout);
+ do_wait ("ld");
+ dump_file (ldout);
+ unlink (ldout);
- /* If -r, don't build the constructor or destructor list, just return now. */
- if (rflag)
+ /* 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;
+ /* 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. */
+
#ifdef COLLECT_SCAN_OBJECTS
/* The AIX linker will discard static constructors in object files if
nothing else in the file is referenced, so look at them first. */
@@ -1347,8 +1450,8 @@ main (argc, argv)
/* Wait for a process to finish, and exit if a non-zero status is found. */
-static void
-do_wait (prog)
+int
+collect_wait (prog)
char *prog;
{
int status;
@@ -1372,28 +1475,35 @@ do_wait (prog)
(status & 0200) ? ", core dumped" : "");
#endif
- my_exit (127);
+ collect_exit (127);
}
if (WIFEXITED (status))
- {
- int ret = WEXITSTATUS (status);
- if (ret != 0)
- {
- error ("%s returned %d exit status", prog, ret);
- my_exit (ret);
- }
- }
+ return WEXITSTATUS (status);
+ }
+ return 0;
+}
+
+static void
+do_wait (prog)
+ char *prog;
+{
+ int ret = collect_wait (prog);
+ if (ret != 0)
+ {
+ error ("%s returned %d exit status", prog, ret);
+ collect_exit (ret);
}
}
/* Fork and execute a program, and wait for the reply. */
-static void
-fork_execute (prog, argv)
+void
+collect_execute (prog, argv, redir)
char *prog;
char **argv;
+ char *redir;
{
int pid;
@@ -1434,13 +1544,28 @@ fork_execute (prog, argv)
if (pid == 0) /* child context */
{
+ if (redir)
+ {
+ unlink (redir);
+ if (freopen (redir, "a", stdout) == NULL)
+ fatal_perror ("redirecting stdout");
+ if (freopen (redir, "a", stderr) == NULL)
+ fatal_perror ("redirecting stderr");
+ }
+
execvp (argv[0], argv);
fatal_perror ("executing %s", prog);
}
+}
+static void
+fork_execute (prog, argv)
+ char *prog;
+ char **argv;
+{
+ collect_execute (prog, argv, NULL);
do_wait (prog);
}
-
/* Unlink a file unless we are debugging. */
@@ -1831,7 +1956,7 @@ scan_prog_file (prog_name, which_pass)
#endif
}
-#ifdef SUNOS4_SHARED_LIBRARIES
+#if SUNOS4_SHARED_LIBRARIES
/* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
that the output file depends upon and their initialization/finalization
@@ -3000,10 +3125,10 @@ end_file (ptr)
fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
}
- free ((generic *)ptr->start);
+ free (ptr->start);
}
- free ((generic *)ptr);
+ free (ptr);
}
#endif /* OBJECT_FORMAT_ROSE */