Commit db126753 by David Edelsohn

[multiple changes]

Thu Feb 19 22:36:53 1998  Andrey Slepuhin  <pooh@msu.net>
			  David Edelsohn  <edelsohn@mhpcc.edu>
	* collect2.c (XCOFF_SCAN_LIBS): Remove.
	(export_flag): New variable.
	(export_file): #ifdef COLLECT_EXPORT_LIST.
	(import_file, exports, imports, undefined): New variables.
	(libs, cmdline_lib_dirs, libpath_lib_dirs, libpath, libexts): Same.
	(dump_list, dump_prefix_list, is_in_list): New functions.
	(write_export_file): $ifdef COLLECT_EXPORT_LIST.
	(write_import_file, resolve_lib_name): New functions.
	(use_import_list, ignore_library): Same.
	(collect_exit): maybe_unlink import_file and #ifdef.
	(handler): Same.
	(main): New variable importf, #ifdef exportf.  Move parsing of
 	-shared before general argument parsing.  Resolve AIX library
 	paths and import libgcc.a symbols.  Treat .so shared libraries the
 	same as objects and .a libraries.  Create alias for object_lst and
 	increment it instead of original pointer.  Scan AIX libraries as
 	objects earlier instead of using scan_libraries.  Perform AIX
 	tlink later to resolve templates instead of forking ld.
	(GCC_OK_SYMBOL): Ensure symbol not in undef section.
	(GCC_UNDEF_SYMBOL): New macro.
	(scan_prog_file): Loop for members of AIX libraries.  Handle
 	export/import of ctors/dtors.
	(aix_std_libs): New variable.
	(scan_libraries, XCOFF): Delete.
Fri Feb 19 22:36:52 1998  Robert Lipe   <robertl@dgii.com>
	* collect2.c (full_real_ld_suffix): #ifdef CROSS_COMPILE.

From-SVN: r18128
parent e642002f
Thu Feb 19 22:36:53 1998 Andrey Slepuhin <pooh@msu.net>
David Edelsohn <edelsohn@mhpcc.edu>
* collect2.c (XCOFF_SCAN_LIBS): Remove.
(export_flag): New variable.
(export_file): #ifdef COLLECT_EXPORT_LIST.
(import_file, exports, imports, undefined): New variables.
(libs, cmdline_lib_dirs, libpath_lib_dirs, libpath, libexts): Same.
(dump_list, dump_prefix_list, is_in_list): New functions.
(write_export_file): $ifdef COLLECT_EXPORT_LIST.
(write_import_file, resolve_lib_name): New functions.
(use_import_list, ignore_library): Same.
(collect_exit): maybe_unlink import_file and #ifdef.
(handler): Same.
(main): New variable importf, #ifdef exportf. Move parsing of
-shared before general argument parsing. Resolve AIX library
paths and import libgcc.a symbols. Treat .so shared libraries the
same as objects and .a libraries. Create alias for object_lst and
increment it instead of original pointer. Scan AIX libraries as
objects earlier instead of using scan_libraries. Perform AIX
tlink later to resolve templates instead of forking ld.
(GCC_OK_SYMBOL): Ensure symbol not in undef section.
(GCC_UNDEF_SYMBOL): New macro.
(scan_prog_file): Loop for members of AIX libraries. Handle
export/import of ctors/dtors.
(aix_std_libs): New variable.
(scan_libraries, XCOFF): Delete.
Thu Feb 19 22:36:52 1998 Robert Lipe <robertl@dgii.com>
* collect2.c (full_real_ld_suffix): #ifdef CROSS_COMPILE.
1998-02-19 Mike Stump <mrs@wrs.com> 1998-02-19 Mike Stump <mrs@wrs.com>
* Makefile.in: Use $tooldir for sys-include to match toplevel * Makefile.in: Use $tooldir for sys-include to match toplevel
......
...@@ -99,7 +99,7 @@ extern char *choose_temp_base (); ...@@ -99,7 +99,7 @@ extern char *choose_temp_base ();
/* On certain systems, we have code that works by scanning the object file /* On certain systems, we have code that works by scanning the object file
directly. But this code uses system-specific header files and library directly. But this code uses system-specific header files and library
functions, so turn it off in a cross-compiler. Likewise, the names of 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. */ cross-versions are in the proper directories. */
#ifdef CROSS_COMPILE #ifdef CROSS_COMPILE
...@@ -112,10 +112,10 @@ extern char *choose_temp_base (); ...@@ -112,10 +112,10 @@ extern char *choose_temp_base ();
#undef REAL_STRIP_FILE_NAME #undef REAL_STRIP_FILE_NAME
#endif #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. run nm to find what symbols are present.
In a cross-compiler, this means you need a cross nm, 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) #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
#define OBJECT_FORMAT_NONE #define OBJECT_FORMAT_NONE
...@@ -147,10 +147,6 @@ extern char *choose_temp_base (); ...@@ -147,10 +147,6 @@ extern char *choose_temp_base ();
#define MY_ISCOFF(X) ISCOFF (X) #define MY_ISCOFF(X) ISCOFF (X)
#endif #endif
#ifdef XCOFF_DEBUGGING_INFO
#define XCOFF_SCAN_LIBS
#endif
#endif /* OBJECT_FORMAT_COFF */ #endif /* OBJECT_FORMAT_COFF */
#ifdef OBJECT_FORMAT_ROSE #ifdef OBJECT_FORMAT_ROSE
...@@ -189,7 +185,7 @@ extern char *choose_temp_base (); ...@@ -189,7 +185,7 @@ extern char *choose_temp_base ();
#define SYMBOL__MAIN __main #define SYMBOL__MAIN __main
#endif #endif
#if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES || defined(XCOFF_SCAN_LIBS) #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
#define SCAN_LIBRARIES #define SCAN_LIBRARIES
#endif #endif
...@@ -234,6 +230,9 @@ extern char *version_string; ...@@ -234,6 +230,9 @@ extern char *version_string;
int vflag; /* true if -v */ int vflag; /* true if -v */
static int rflag; /* true if -r */ static int rflag; /* true if -r */
static int strip_flag; /* true if -s */ static int strip_flag; /* true if -s */
#ifdef COLLECT_EXPORT_LIST
static int export_flag; /* true if -bE */
#endif
int debug; /* true if -debug */ int debug; /* true if -debug */
...@@ -243,7 +242,10 @@ static int temp_filename_length; /* Length of temp_filename */ ...@@ -243,7 +242,10 @@ static int temp_filename_length; /* Length of temp_filename */
static char *temp_filename; /* Base of temp filenames */ static char *temp_filename; /* Base of temp filenames */
static char *c_file; /* <xxx>.c for constructor/destructor list. */ static char *c_file; /* <xxx>.c for constructor/destructor list. */
static char *o_file; /* <xxx>.o 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 *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. */ char *ldout; /* File for ld errors. */
static char *output_file; /* Output file for ld. */ static char *output_file; /* Output file for ld. */
static char *nm_file_name; /* pathname of nm */ static char *nm_file_name; /* pathname of nm */
...@@ -254,7 +256,11 @@ static char *initname, *fininame; /* names of init and fini funcs */ ...@@ -254,7 +256,11 @@ static char *initname, *fininame; /* names of init and fini funcs */
static struct head constructors; /* list of constructors found */ static struct head constructors; /* list of constructors found */
static struct head destructors; /* list of destructors found */ static struct head destructors; /* list of destructors found */
#ifdef COLLECT_EXPORT_LIST
static struct head exports; /* list of exported symbols */ 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 */ static struct head frame_tables; /* list of frame unwind info tables */
struct obstack temporary_obstack; struct obstack temporary_obstack;
...@@ -284,6 +290,16 @@ struct path_prefix ...@@ -284,6 +290,16 @@ struct path_prefix
char *name; /* Name of this list (used in config stuff) */ char *name; /* Name of this list (used in config stuff) */
}; };
#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
void collect_exit PROTO((int)); void collect_exit PROTO((int));
void collect_execute PROTO((char *, char **, char *)); void collect_execute PROTO((char *, char **, char *));
void dump_file PROTO((char *)); void dump_file PROTO((char *));
...@@ -299,13 +315,22 @@ static void fork_execute PROTO((char *, char **)); ...@@ -299,13 +315,22 @@ static void fork_execute PROTO((char *, char **));
static void maybe_unlink PROTO((char *)); static void maybe_unlink PROTO((char *));
static void add_to_list PROTO((struct head *, char *)); static void add_to_list PROTO((struct head *, char *));
static void write_list PROTO((FILE *, char *, struct id *)); static void write_list PROTO((FILE *, char *, struct id *));
static void dump_list PROTO((FILE *, char *, struct id *));
static void dump_prefix_list PROTO((FILE *, char *, struct prefix_list *));
static int is_in_list PROTO((char *, struct id *));
static void write_list_with_asm PROTO((FILE *, char *, struct id *)); static void write_list_with_asm PROTO((FILE *, char *, struct id *));
static void write_c_file PROTO((FILE *, char *)); static void write_c_file PROTO((FILE *, char *));
static void write_export_file PROTO((FILE *));
static void scan_prog_file PROTO((char *, enum pass)); static void scan_prog_file PROTO((char *, enum pass));
#ifdef SCAN_LIBRARIES #ifdef SCAN_LIBRARIES
static void scan_libraries PROTO((char *)); static void scan_libraries PROTO((char *));
#endif #endif
#ifdef COLLECT_EXPORT_LIST
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 *xcalloc ();
char *xmalloc (); char *xmalloc ();
...@@ -378,9 +403,14 @@ collect_exit (status) ...@@ -378,9 +403,14 @@ collect_exit (status)
if (o_file != 0 && o_file[0]) if (o_file != 0 && o_file[0])
maybe_unlink (o_file); maybe_unlink (o_file);
#ifdef COLLECT_EXPORT_LIST
if (export_file != 0 && export_file[0]) if (export_file != 0 && export_file[0])
maybe_unlink (export_file); maybe_unlink (export_file);
if (import_file != 0 && import_file[0])
maybe_unlink (import_file);
#endif
if (ldout != 0 && ldout[0]) if (ldout != 0 && ldout[0])
{ {
dump_file (ldout); dump_file (ldout);
...@@ -454,9 +484,14 @@ handler (signo) ...@@ -454,9 +484,14 @@ handler (signo)
if (ldout != 0 && ldout[0]) if (ldout != 0 && ldout[0])
maybe_unlink (ldout); maybe_unlink (ldout);
#ifdef COLLECT_EXPORT_LIST
if (export_file != 0 && export_file[0]) if (export_file != 0 && export_file[0])
maybe_unlink (export_file); maybe_unlink (export_file);
if (import_file != 0 && import_file[0])
maybe_unlink (import_file);
#endif
signal (signo, SIG_DFL); signal (signo, SIG_DFL);
kill (getpid (), signo); kill (getpid (), signo);
} }
...@@ -639,7 +674,7 @@ is_ctor_dtor (s) ...@@ -639,7 +674,7 @@ is_ctor_dtor (s)
#endif #endif
{ "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 }, { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
{ "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 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; cfront has its own linker procedure to collect them;
if collect2 gets them too, they get collected twice if collect2 gets them too, they get collected twice
when the cfront procedure is run and the compiler used when the cfront procedure is run and the compiler used
...@@ -925,7 +960,9 @@ main (argc, argv) ...@@ -925,7 +960,9 @@ main (argc, argv)
char *ld_suffix = "ld"; char *ld_suffix = "ld";
char *full_ld_suffix = ld_suffix; char *full_ld_suffix = ld_suffix;
char *real_ld_suffix = "real-ld"; char *real_ld_suffix = "real-ld";
#ifdef CROSS_COMPILE
char *full_real_ld_suffix = real_ld_suffix; char *full_real_ld_suffix = real_ld_suffix;
#endif
char *collect_ld_suffix = "collect-ld"; char *collect_ld_suffix = "collect-ld";
char *nm_suffix = "nm"; char *nm_suffix = "nm";
char *full_nm_suffix = nm_suffix; char *full_nm_suffix = nm_suffix;
...@@ -940,7 +977,11 @@ main (argc, argv) ...@@ -940,7 +977,11 @@ main (argc, argv)
char *gstrip_suffix = "gstrip"; char *gstrip_suffix = "gstrip";
char *full_gstrip_suffix = gstrip_suffix; char *full_gstrip_suffix = gstrip_suffix;
char *arg; char *arg;
FILE *outf, *exportf; FILE *outf;
#ifdef COLLECT_EXPORT_LIST
FILE *exportf;
FILE *importf;
#endif
char *ld_file_name; char *ld_file_name;
char *collect_name; char *collect_name;
char *collect_names; char *collect_names;
...@@ -978,12 +1019,12 @@ main (argc, argv) ...@@ -978,12 +1019,12 @@ main (argc, argv)
In practice, collect will rarely invoke itself. This can happen now In practice, collect will rarely invoke itself. This can happen now
that we are no longer called gld. A perfect example is when running 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 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. */ ld, we will find our installed version and believe that's the real ld. */
/* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the /* 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 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 handled two levels of recursion). If we do not we may mutually recurse
forever. This can happen (I think) when bootstrapping the old version forever. This can happen (I think) when bootstrapping the old version
and a new one is installed (rare, but we should handle it). and a new one is installed (rare, but we should handle it).
??? Hopefully references to COLLECT_NAME can be removed at some point. */ ??? Hopefully references to COLLECT_NAME can be removed at some point. */
...@@ -1006,7 +1047,7 @@ main (argc, argv) ...@@ -1006,7 +1047,7 @@ main (argc, argv)
prefix_from_env ("COLLECT_NAMES", &our_file_names); prefix_from_env ("COLLECT_NAMES", &our_file_names);
/* Set environment variable COLLECT_NAME to our name so the previous version /* 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. of collect will not find us. If it does we will mutually recurse forever.
This can happen when bootstrapping the new version and an old version is This can happen when bootstrapping the new version and an old version is
installed. installed.
??? Hopefully this bit of code can be removed at some point. */ ??? Hopefully this bit of code can be removed at some point. */
...@@ -1207,17 +1248,49 @@ main (argc, argv) ...@@ -1207,17 +1248,49 @@ main (argc, argv)
temp_filename_length = strlen (temp_filename); temp_filename_length = strlen (temp_filename);
c_file = xcalloc (temp_filename_length + sizeof (".c"), 1); c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);
o_file = xcalloc (temp_filename_length + sizeof (".o"), 1); o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);
#ifdef COLLECT_EXPORT_LIST
export_file = xmalloc (temp_filename_length + sizeof (".x")); export_file = xmalloc (temp_filename_length + sizeof (".x"));
import_file = xmalloc (temp_filename_length + sizeof (".p"));
#endif
ldout = xmalloc (temp_filename_length + sizeof (".ld")); ldout = xmalloc (temp_filename_length + sizeof (".ld"));
sprintf (ldout, "%s.ld", temp_filename); sprintf (ldout, "%s.ld", temp_filename);
sprintf (c_file, "%s.c", temp_filename); sprintf (c_file, "%s.c", temp_filename);
sprintf (o_file, "%s.o", temp_filename); sprintf (o_file, "%s.o", temp_filename);
#ifdef COLLECT_EXPORT_LIST
sprintf (export_file, "%s.x", temp_filename); sprintf (export_file, "%s.x", temp_filename);
sprintf (import_file, "%s.p", temp_filename);
#endif
*c_ptr++ = c_file_name; *c_ptr++ = c_file_name;
*c_ptr++ = "-c"; *c_ptr++ = "-c";
*c_ptr++ = "-o"; *c_ptr++ = "-o";
*c_ptr++ = o_file; *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 = (char *) 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, /* !!! When GCC calls collect2,
it does not know whether it is calling collect2 or ld. it does not know whether it is calling collect2 or ld.
So collect2 cannot meaningfully understand any options So collect2 cannot meaningfully understand any options
...@@ -1237,6 +1310,15 @@ main (argc, argv) ...@@ -1237,6 +1310,15 @@ main (argc, argv)
{ {
switch (arg[1]) 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;
break;
#endif
case 'd': case 'd':
if (!strcmp (arg, "-debug")) if (!strcmp (arg, "-debug"))
{ {
...@@ -1256,7 +1338,31 @@ main (argc, argv) ...@@ -1256,7 +1338,31 @@ main (argc, argv)
*ld2++ = o_file; *ld2++ = o_file;
*ld2++ = arg; *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; break;
#endif
case 'o': case 'o':
if (arg[2] == '\0') if (arg[2] == '\0')
...@@ -1274,7 +1380,7 @@ main (argc, argv) ...@@ -1274,7 +1380,7 @@ main (argc, argv)
if (arg[2] == '\0' && do_collecting) if (arg[2] == '\0' && do_collecting)
{ {
/* We must strip after the nm run, otherwise C++ linking /* 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. */ else with strip if there is no second ld run. */
strip_flag = 1; strip_flag = 1;
ld1--; ld1--;
...@@ -1288,7 +1394,8 @@ main (argc, argv) ...@@ -1288,7 +1394,8 @@ main (argc, argv)
} }
} }
else if ((p = rindex (arg, '.')) != (char *) 0 else if ((p = rindex (arg, '.')) != (char *) 0
&& (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0)) && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
|| strcmp (p, ".so") == 0))
{ {
if (first_file) if (first_file)
{ {
...@@ -1305,39 +1412,66 @@ main (argc, argv) ...@@ -1305,39 +1412,66 @@ main (argc, argv)
} }
if (p[1] == 'o') if (p[1] == 'o')
*object++ = arg; *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. */ #ifdef COLLECT_EXPORT_LIST
p = (char *) getenv ("COLLECT_GCC_OPTIONS"); /* This is added only for debugging purposes. */
while (p && *p) if (debug)
{ {
char *q = extract_string (&p); fprintf (stderr, "List of libraries:\n");
if (*q == '-' && (q[1] == 'm' || q[1] == 'f')) dump_list (stderr, "\t", libs.first);
*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";
#ifdef COLLECT_EXPORT_LIST
/* The AIX linker will discard static constructors in object files if /* The AIX linker will discard static constructors in object files if
nothing else in the file is referenced, so look at them first. */ 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); char **export_object_lst = object_lst;
sprintf (buf, "-bE:%s", export_file); while (export_object_lst < object)
*ld1++ = buf; scan_prog_file (*export_object_lst++, PASS_OBJ);
*ld2++ = buf; }
{
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"); exportf = fopen (export_file, "w");
if (exportf == (FILE *) 0) if (exportf == (FILE *) 0)
fatal_perror ("%s", export_file); fatal_perror ("%s", export_file);
write_export_file (exportf); write_export_file (exportf);
if (fclose (exportf)) if (fclose (exportf))
fatal_perror ("closing %s", export_file); 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 #endif
...@@ -1399,23 +1533,32 @@ main (argc, argv) ...@@ -1399,23 +1533,32 @@ main (argc, argv)
/* Load the program, searching all libraries and attempting to provide /* Load the program, searching all libraries and attempting to provide
undefined symbols from repository information. */ undefined symbols from repository information. */
do_tlink (ld1_argv, object_lst); /* On AIX we do this later. */
#ifndef COLLECT_EXPORT_LIST
do_tlink (ld1_argv, object_lst);
#else
/* If -r or they'll be run via some other method, don't build the /* If -r or they will be run via some other method, do not build the
constructor or destructor list, just return now. */ constructor or destructor list, just return now. */
if (rflag || ! do_collecting) if (rflag || ! do_collecting)
{ {
/* But make sure we delete the export file we may have created. */ /* But make sure we delete the export file we may have created. */
if (export_file != 0 && export_file[0]) if (export_file != 0 && export_file[0])
maybe_unlink (export_file); maybe_unlink (export_file);
if (import_file != 0 && import_file[0])
maybe_unlink (import_file);
return 0; return 0;
} }
#endif
/* Examine the namelist with nm and search it for static constructors /* Examine the namelist with nm and search it for static constructors
and destructors to call. 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); scan_prog_file (output_file, PASS_FIRST);
#endif
#ifdef SCAN_LIBRARIES #ifdef SCAN_LIBRARIES
scan_libraries (output_file); scan_libraries (output_file);
...@@ -1429,14 +1572,18 @@ main (argc, argv) ...@@ -1429,14 +1572,18 @@ main (argc, argv)
if (constructors.number == 0 && destructors.number == 0 if (constructors.number == 0 && destructors.number == 0
&& frame_tables.number == 0 && frame_tables.number == 0
#ifdef SCAN_LIBRARIES #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
/* If we will be running these functions ourselves, we want to emit /* 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. */ dependent programs when we add static objects. */
&& ! shared_obj && ! shared_obj
#endif #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. */ /* Strip now if it was requested on the command line. */
if (strip_flag) if (strip_flag)
{ {
...@@ -1449,6 +1596,7 @@ main (argc, argv) ...@@ -1449,6 +1596,7 @@ main (argc, argv)
#ifdef COLLECT_EXPORT_LIST #ifdef COLLECT_EXPORT_LIST
maybe_unlink (export_file); maybe_unlink (export_file);
maybe_unlink (import_file);
#endif #endif
return 0; return 0;
} }
...@@ -1505,15 +1653,26 @@ main (argc, argv) ...@@ -1505,15 +1653,26 @@ main (argc, argv)
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); 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); fork_execute ("ld", ld2_argv);
/* Let scan_prog_file do any final mods (OSF/rose needs this for /* Let scan_prog_file do any final mods (OSF/rose needs this for
constructors/destructors in shared libraries. */ constructors/destructors in shared libraries. */
scan_prog_file (output_file, PASS_SECOND); scan_prog_file (output_file, PASS_SECOND);
#endif
maybe_unlink (c_file); maybe_unlink (c_file);
maybe_unlink (o_file); maybe_unlink (o_file);
#ifdef COLLECT_EXPORT_LIST
maybe_unlink (export_file); maybe_unlink (export_file);
maybe_unlink (import_file);
#endif
return 0; return 0;
} }
...@@ -1596,8 +1755,8 @@ collect_execute (prog, argv, redir) ...@@ -1596,8 +1755,8 @@ collect_execute (prog, argv, redir)
fflush (stdout); fflush (stdout);
fflush (stderr); fflush (stderr);
/* If we can't find a program we need, complain error. Do this here /* If we cannot find a program we need, complain error. Do this here
since we might not end up needing something that we couldn't find. */ since we might not end up needing something that we could not find. */
if (argv[0] == 0) if (argv[0] == 0)
fatal ("cannot find `%s'", prog); fatal ("cannot find `%s'", prog);
...@@ -1700,6 +1859,47 @@ write_list (stream, prefix, list) ...@@ -1700,6 +1859,47 @@ write_list (stream, prefix, 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;
}
/* Added for debugging purpose. */
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;
}
}
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;
}
}
static void static void
write_list_with_asm (stream, prefix, list) write_list_with_asm (stream, prefix, list)
FILE *stream; FILE *stream;
...@@ -1930,6 +2130,7 @@ write_c_file (stream, name) ...@@ -1930,6 +2130,7 @@ write_c_file (stream, name)
fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n"); fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
} }
#ifdef COLLECT_EXPORT_LIST
static void static void
write_export_file (stream) write_export_file (stream)
FILE *stream; FILE *stream;
...@@ -1938,6 +2139,17 @@ write_export_file (stream) ...@@ -1938,6 +2139,17 @@ write_export_file (stream)
for (; list; list = list->next) for (; list; list = list->next)
fprintf (stream, "%s\n", list->name); 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 #ifdef OBJECT_FORMAT_NONE
...@@ -1967,7 +2179,7 @@ scan_prog_file (prog_name, which_pass) ...@@ -1967,7 +2179,7 @@ scan_prog_file (prog_name, which_pass)
if (which_pass == PASS_SECOND) if (which_pass == PASS_SECOND)
return; return;
/* If we don't have an `nm', complain. */ /* If we do not have an `nm', complain. */
if (nm_file_name == 0) if (nm_file_name == 0)
fatal ("cannot find `nm'"); fatal ("cannot find `nm'");
...@@ -2057,7 +2269,7 @@ scan_prog_file (prog_name, which_pass) ...@@ -2057,7 +2269,7 @@ scan_prog_file (prog_name, which_pass)
name = p; name = p;
/* Find the end of the symbol name. /* Find the end of the symbol name.
Don't include `|', because Encore nm can tack that on the end. */ Do not include `|', because Encore nm can tack that on the end. */
for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|'; for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';
end++) end++)
continue; continue;
...@@ -2181,7 +2393,7 @@ libselect (d) ...@@ -2181,7 +2393,7 @@ libselect (d)
We must verify that the extension is numeric, because Sun saves the We must verify that the extension is numeric, because Sun saves the
original versions of patched libraries with a .FCS extension. Files with 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 static int
libcompare (d1, d2) libcompare (d1, d2)
...@@ -2409,7 +2621,7 @@ scan_libraries (prog_name) ...@@ -2409,7 +2621,7 @@ scan_libraries (prog_name)
char buf[1024]; char buf[1024];
FILE *inf; FILE *inf;
/* If we don't have an `ldd', complain. */ /* If we do not have an `ldd', complain. */
if (ldd_file_name == 0) if (ldd_file_name == 0)
{ {
error ("cannot find `ldd'"); error ("cannot find `ldd'");
...@@ -2554,8 +2766,11 @@ scan_libraries (prog_name) ...@@ -2554,8 +2766,11 @@ scan_libraries (prog_name)
# define GCC_SYMENT SYMENT # define GCC_SYMENT SYMENT
# define GCC_OK_SYMBOL(X) \ # define GCC_OK_SYMBOL(X) \
(((X).n_sclass == C_EXT) && \ (((X).n_sclass == C_EXT) && \
(((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \ ((X).n_scnum > N_UNDEF) && \
((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))) (((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_SYMINC(X) ((X).n_numaux+1)
# define GCC_SYMZERO(X) 0 # define GCC_SYMZERO(X) 0
# define GCC_CHECK_HDR(X) (1) # define GCC_CHECK_HDR(X) (1)
...@@ -2579,246 +2794,264 @@ scan_prog_file (prog_name, which_pass) ...@@ -2579,246 +2794,264 @@ scan_prog_file (prog_name, which_pass)
{ {
LDFILE *ldptr = NULL; LDFILE *ldptr = NULL;
int sym_index, sym_count; 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) if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
return; return;
if ((ldptr = ldopen (prog_name, ldptr)) == NULL) #ifdef COLLECT_EXPORT_LIST
fatal ("%s: can't open as COFF file", prog_name); /* We do not need scanning for some standard C libraries. */
if (which_pass == PASS_FIRST && ignore_library (prog_name))
if (!MY_ISCOFF (HEADER (ldptr).f_magic)) return;
fatal ("%s: not a COFF file", prog_name);
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); #endif
sym_index = GCC_SYMZERO (ldptr); if ((ldptr = ldopen (prog_name, ldptr)) != NULL)
while (sym_index < sym_count)
{ {
GCC_SYMENT symbol;
if (ldtbread (ldptr, sym_index, &symbol) <= 0) if (!MY_ISCOFF (HEADER (ldptr).f_magic))
break; fatal ("%s: not a COFF file", prog_name);
sym_index += GCC_SYMINC (symbol);
if (GCC_OK_SYMBOL (symbol)) #ifdef COLLECT_EXPORT_LIST
/* Is current archive member a shared object? */
is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
#endif
if (GCC_CHECK_HDR (ldptr))
{ {
char *name; 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 (GCC_OK_SYMBOL (symbol))
{
char *name;
if ((name = ldgetname (ldptr, &symbol)) == NULL) if ((name = ldgetname (ldptr, &symbol)) == NULL)
continue; /* should never happen */ continue; /* should never happen */
#ifdef XCOFF_DEBUGGING_INFO #ifdef XCOFF_DEBUGGING_INFO
/* All AIX function names have a duplicate entry beginning /* All AIX function names have a duplicate entry
with a dot. */ beginning with a dot. */
if (*name == '.') if (*name == '.')
++name; ++name;
#endif #endif
switch (is_ctor_dtor (name)) switch (is_ctor_dtor (name))
{ {
case 1: case 1:
add_to_list (&constructors, name); if (! is_shared) add_to_list (&constructors, name);
if (which_pass == PASS_OBJ) if (which_pass == PASS_OBJ)
add_to_list (&exports, name); add_to_list (&exports, name);
break; #ifdef COLLECT_EXPORT_LIST
/* 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);
if (which_pass == PASS_OBJ)
add_to_list (&exports, name);
#ifdef COLLECT_EXPORT_LIST
/* 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: #ifdef COLLECT_EXPORT_LIST
add_to_list (&destructors, name); case 3:
if (which_pass == PASS_OBJ) if (is_shared)
add_to_list (&exports, name); add_to_list (&constructors, name);
break; break;
default: /* not a constructor or destructor */ case 4:
continue; 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 !defined(EXTENDED_COFF)
if (debug) if (debug)
fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n", fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
symbol.n_scnum, symbol.n_sclass, symbol.n_scnum, symbol.n_sclass,
(symbol.n_type ? "0" : ""), symbol.n_type, (symbol.n_type ? "0" : ""), symbol.n_type,
name); name);
#else #else
if (debug) if (debug)
fprintf (stderr, "\tiss = %5d, value = %5d, index = %5d, name = %s\n", fprintf (stderr,
symbol.iss, symbol.value, symbol.index, name); "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
symbol.iss, 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 #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); (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 #ifdef COLLECT_EXPORT_LIST
scan_libraries (prog_name)
/* 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; char *prog_name;
{ {
LDFILE *ldptr; char *p;
SCNHDR ldsh;
static struct path_prefix libpath; /* we should only do this once */
if ((ldptr = ldopen (prog_name, ldptr)) == NULL) /* If we do not build a shared object then import list should not be used. */
fatal ("%s: can't open as COFF file", prog_name); if (! shared_obj) return 0;
if (!MY_ISCOFF (HEADER (ldptr).f_magic))
fatal ("%s: not a COFF file", prog_name);
/* find and read loader section */ /* Currently we check only for libgcc, but this can be changed in future. */
if (ldnshread (ldptr, _LOADER, &ldsh)) p = strstr (prog_name, "libgcc.a");
{ if (p != 0 && (strlen (p) == sizeof ("libgcc.a") - 1))
LDHDR ldh; return 1;
char *impbuf; return 0;
int entry; }
FSEEK (ldptr, ldsh.s_scnptr, BEGINNING); /* Given a library name without "lib" prefix, this function
FREAD (&ldh, sizeof (ldh), 1, ldptr); returns a full library name including a path. */
/* read import library list */ static char *
impbuf = alloca (ldh.l_istlen); resolve_lib_name (name)
FSEEK (ldptr, ldh.l_impoff + ldsh.s_scnptr, BEGINNING); char *name;
FREAD (impbuf, ldh.l_istlen, 1, ldptr); {
char *lib_buf;
int i, j, l = 0;
if (debug) for (i = 0; libpaths[i]; i++)
fprintf (stderr, "LIBPATH=%s\n", impbuf); if (libpaths[i]->max_len > l)
prefix_from_string (impbuf, &libpath); l = libpaths[i]->max_len;
/* skip LIBPATH and empty base and member fields */ lib_buf = xmalloc (l + strlen(name) + 10);
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;
}
}
if (! soname) for (i = 0; libpaths[i]; i++)
fatal ("%s: library not found", implib); {
if (debug) struct prefix_list *list = libpaths[i]->plist;
if (*impmem) for (; list; list = list->next)
fprintf (stderr, "%s (%s)\n", soname, impmem); {
else for (j = 0; libexts[j]; j++)
fprintf (stderr, "%s\n", soname);
do
{ {
/* scan imported shared objects for GCC GLOBAL ctors */ /* The following lines are needed because path_prefix list
short type; may contain directories both with trailing '/' and
if ((libptr = ldopen (soname, libptr)) == NULL) without it. */
fatal ("%s: can't open import library", soname); char *p = "";
if (TYPE (libptr) == ARTYPE) if (list->prefix[strlen(list->prefix)-1] != '/')
{ p = "/";
LDFILE *memptr; sprintf (lib_buf, "%s%slib%s.%s",
if (! *impmem) list->prefix, p, name, libexts[j]);
fatal ("%s: no archive member specified", soname); if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
ldahread (libptr, &ah); if (file_exists (lib_buf))
if (strcmp (ah.ar_name, impmem))
continue;
}
type = HEADER (libptr).f_magic;
if (HEADER (libptr).f_flags & F_SHROBJ)
{ {
SCNHDR soldsh; if (debug) fprintf (stderr, "found: %s\n", lib_buf);
LDHDR soldh; return (lib_buf);
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;
}
}
}
} }
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 */ #endif /* OBJECT_FORMAT_COFF */
...@@ -2912,7 +3145,7 @@ scan_prog_file (prog_name, which_pass) ...@@ -2912,7 +3145,7 @@ scan_prog_file (prog_name, which_pass)
prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY); prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
if (prog_fd < 0) 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_file = read_file (prog_name, prog_fd, rw);
obj = obj_file->start; obj = obj_file->start;
...@@ -3084,7 +3317,7 @@ scan_prog_file (prog_name, which_pass) ...@@ -3084,7 +3317,7 @@ scan_prog_file (prog_name, which_pass)
fatal ("no cmd_strings found"); fatal ("no cmd_strings found");
/* Add __main to initializer list. /* 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 do anything, since in the current version, you cannot do mallocs
and such in the constructors. */ and such in the constructors. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment