#include <signal.h>
#include <sys/file.h>
#include <sys/stat.h>
+#ifdef NO_WAIT_H
#include <sys/wait.h>
+#endif
#ifndef errno
extern int errno;
static int vflag; /* true if -v */
static int rflag; /* true if -r */
+static int strip_flag; /* true if -s */
static int debug; /* true if -debug */
static char *c_file; /* <xxx>.c for constructor/destructor list. */
static char *o_file; /* <xxx>.o for constructor/destructor list. */
static char *nm_file_name; /* pathname of nm */
+static char *strip_file_name; /* pathname of strip */
static struct head constructors; /* list of constructors found */
static struct head destructors; /* list of destructors found */
extern char *getenv ();
extern char *mktemp ();
-extern int vfork ();
static void add_to_list ();
static void scan_prog_file ();
static void fork_execute ();
{
char *q = p;
while (*q && *q != ' ') q++;
- if (*p == '-' && (p[1] == 'm' || p[1] == 'f'))
+ if (*p == '-' && p[1] == 'm')
num_c_args++;
if (*q) q++;
signal (SIGSEGV, handler);
signal (SIGBUS, handler);
- /* Try to discover a valid linker/assembler/nm to use. */
+ /* Try to discover a valid linker/assembler/nm/strip to use. */
len = strlen (argv[0]);
prefix = (char *)0;
if (len >= sizeof ("ld")-1)
clen = sizeof (STANDARD_EXEC_PREFIX) - 1;
#endif
+ /* Allocate enough string space for the longest possible pathnames. */
ld_file_name = xcalloc (len + sizeof ("real-ld"), 1);
nm_file_name = xcalloc (len + sizeof ("gnm"), 1);
+ strip_file_name = xcalloc (len + sizeof ("gstrip"), 1);
- memcpy (ld_file_name, prefix, len);
+ /* Determine the full path name of the ld program to use. */
+ bcopy (prefix, ld_file_name, len);
strcpy (ld_file_name + len, "real-ld");
if (access (ld_file_name, X_OK) < 0)
{
#ifdef REAL_LD_FILE_NAME
ld_file_name = REAL_LD_FILE_NAME;
#else
- ld_file_name = (access ("/usr/bin/ld", X_OK) == 0) ? "/usr/bin/ld" : "/bin/ld";
+ ld_file_name = (access ("/usr/bin/ld", X_OK) == 0
+ ? "/usr/bin/ld" : "/bin/ld");
#endif
}
}
+ /* Determine the full path name of the C compiler to use. */
c_file_name = getenv ("COLLECT_GCC");
if (c_file_name == 0 || c_file_name[0] != '/')
{
c_file_name = xcalloc (clen + sizeof ("gcc"), 1);
- memcpy (c_file_name, prefix, len);
+ bcopy (prefix, c_file_name, len);
strcpy (c_file_name + len, "gcc");
if (access (c_file_name, X_OK) < 0)
{
}
}
- memcpy (nm_file_name, prefix, len);
+ /* Determine the full path name of the nm to use. */
+ bcopy (prefix, nm_file_name, len);
strcpy (nm_file_name + len, "nm");
if (access (nm_file_name, X_OK) < 0)
{
#ifdef REAL_NM_FILE_NAME
nm_file_name = REAL_NM_FILE_NAME;
#else
- nm_file_name = (access ("/usr/bin/nm", X_OK) == 0) ? "/usr/bin/nm" : "/bin/nm";
+ nm_file_name = (access ("/usr/bin/nm", X_OK) == 0
+ ? "/usr/bin/nm" : "/bin/nm");
+#endif
+ }
+ }
+
+ /* Determine the full pathname of the strip to use. */
+ bcopy (prefix, strip_file_name, len);
+ strcpy (strip_file_name + len, "strip");
+ if (access (strip_file_name, X_OK) < 0)
+ {
+ strcpy (strip_file_name + len, "gstrip");
+ if (access (strip_file_name, X_OK) < 0)
+ {
+ free (strip_file_name);
+#ifdef REAL_STRIP_FILE_NAME
+ strip_file_name = REAL_STRIP_FILE_NAME;
+#else
+ strip_file_name = (access ("/usr/bin/strip", X_OK) == 0
+ ? "/usr/bin/strip" : "/bin/strip");
#endif
}
}
rflag = 1;
break;
+ case 's':
+ if (arg[2] == '\0')
+ {
+ /* We must strip after the nm run, otherwise C++ linking
+ won't work. Thus we strip in the second ld run, or
+ else with strip if there is no second ld run. */
+ strip_flag = 1;
+ ld1--;
+ }
+ break;
+
case 'v':
if (arg[2] == '\0')
vflag = 1;
}
if (constructors.number == 0 && destructors.number == 0)
- return 0;
+ {
+ /* Strip now if it was requested on the command line. */
+ if (strip_flag)
+ {
+ char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
+ strip_argv[0] = "strip";
+ strip_argv[1] = outfile;
+ strip_argv[2] = (char *) 0;
+ fork_execute (strip_file_name, strip_argv);
+ }
+ return 0;
+ }
outf = fopen (c_file, "w");
if (outf == (FILE *)0)
fprintf (stream, "typedef void entry_pt();\n\n");
- write_list_with_asm (stream, "entry_pt ", constructors.first);
+ write_list_with_asm (stream, "extern entry_pt ", constructors.first);
fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number);
write_list (stream, "\t", constructors.first);
fprintf (stream, "\t0\n};\n\n");
- write_list_with_asm (stream, "entry_pt ", destructors.first);
+ 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);
#ifdef OBJECT_FORMAT_COFF
#if defined(EXTENDED_COFF)
-# define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax+SYMHEADER(X).iextMax)
-# define GCC_SYMENT SYMR
-# define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
-# define GCC_SYMINC(X) (1)
-# define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
+# 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_SYMINC(X) (1)
+# define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
+# define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
#else
-# define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
-# define GCC_SYMENT SYMENT
+# define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
+# 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)))
-# define GCC_SYMINC(X) ((X).n_numaux+1)
-# define GCC_SYMZERO(X) 0
+# define GCC_SYMINC(X) ((X).n_numaux+1)
+# define GCC_SYMZERO(X) 0
+# define GCC_CHECK_HDR(X) (1)
#endif
extern char *ldgetname ();
if (!ISCOFF (HEADER(ldptr).f_magic))
fatal ("%s: not a COFF file", prog_name);
- sym_count = GCC_SYMBOLS (ldptr);
- sym_index = GCC_SYMZERO (ldptr);
- while (sym_index < sym_count)
+ if (GCC_CHECK_HDR (ldptr))
{
- GCC_SYMENT symbol;
+ sym_count = GCC_SYMBOLS (ldptr);
+ sym_index = GCC_SYMZERO (ldptr);
+ while (sym_index < sym_count)
+ {
+ GCC_SYMENT symbol;
- if (ldtbread (ldptr, sym_index, &symbol) <= 0)
- break;
- sym_index += GCC_SYMINC (symbol);
+ if (ldtbread (ldptr, sym_index, &symbol) <= 0)
+ break;
+ sym_index += GCC_SYMINC (symbol);
- if (GCC_OK_SYMBOL (symbol))
- {
- char *name;
+ if (GCC_OK_SYMBOL (symbol))
+ {
+ char *name;
- if ((name = ldgetname (ldptr, &symbol)) == NULL)
- continue; /* should never happen */
+ if ((name = ldgetname (ldptr, &symbol)) == NULL)
+ continue; /* should never happen */
#ifdef _AIX
- /* All AIX function names begin with a dot. */
- if (*name++ != '.')
- continue;
+ /* All AIX function names begin with a dot. */
+ if (*name++ != '.')
+ continue;
#endif
- switch (is_ctor_dtor (name))
- {
- case 1:
- add_to_list (&constructors, name);
- break;
+ switch (is_ctor_dtor (name))
+ {
+ case 1:
+ add_to_list (&constructors, name);
+ break;
- case 2:
- add_to_list (&destructors, name);
- break;
+ case 2:
+ add_to_list (&destructors, name);
+ break;
- default: /* not a constructor or destructor */
- continue;
- }
+ default: /* not a constructor or destructor */
+ 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 = %5d, index = %5d, name = %s\n",
+ symbol.iss, symbol.value, symbol.index, name);
#endif
+ }
}
}
if (rw)
{
load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
- memcpy (ptr, load_hdr, load_hdr->hdr.ldci_cmd_size);
+ bcopy (load_hdr, ptr, load_hdr->hdr.ldci_cmd_size);
load_hdr = ptr;
/* null out old command map, because we will rewrite at the end. */
if (debug)
print_load_command (load_hdr, offset, i);
- memcpy (obj + offset, load_hdr, size);
+ bcopy (load_hdr, obj + offset, size);
offset += size;
}
}