Deleted Added
full compact
collect2.c (18336) collect2.c (50397)
1/* Collect static initialization info into data structures
2 that can be traversed by C++ initialization and finalization
3 routines.
4
5 Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
1/* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
3 Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc.
6 Contributed by Chris Smith (csmith@convex.com).
7 Heavily modified by Michael Meissner (meissner@cygnus.com),
8 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
9
10This file is part of GNU CC.
11
12GNU CC is free software; you can redistribute it and/or modify
13it under the terms of the GNU General Public License as published by
14the Free Software Foundation; either version 2, or (at your option)
15any later version.
16
17GNU CC is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with GNU CC; see the file COPYING. If not, write to
24the Free Software Foundation, 59 Temple Place - Suite 330,
25Boston, MA 02111-1307, USA. */
26
27
4 Contributed by Chris Smith (csmith@convex.com).
5 Heavily modified by Michael Meissner (meissner@cygnus.com),
6 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
7
8This file is part of GNU CC.
9
10GNU CC is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2, or (at your option)
13any later version.
14
15GNU CC is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with GNU CC; see the file COPYING. If not, write to
22the Free Software Foundation, 59 Temple Place - Suite 330,
23Boston, MA 02111-1307, USA. */
24
25
28/* Build tables of static constructors and destructors and run ld. */
26/* Build tables of static constructors and destructors and run ld. */
29
30#include "config.h"
27
28#include "config.h"
31#include <sys/types.h>
32#include <stdio.h>
33#include <ctype.h>
34#include <errno.h>
29#include "system.h"
35#include <signal.h>
30#include <signal.h>
36#include <sys/file.h>
37#include <sys/stat.h>
31#include <sys/stat.h>
38#ifdef NO_WAIT_H
39#include <sys/wait.h>
40#endif
41
42#define COLLECT
43
44#include "demangle.h"
45#include "obstack.h"
32
33#define COLLECT
34
35#include "demangle.h"
36#include "obstack.h"
46
47#ifndef errno
48extern int errno;
37#include "gansidecl.h"
38#ifdef __CYGWIN32__
39#include <process.h>
49#endif
50
40#endif
41
51#ifndef HAVE_STRERROR
52#if defined(bsd4_4)
53extern const char *const sys_errlist[];
54#else
55extern char *sys_errlist[];
56#endif
57extern int sys_nerr;
58#else
59char *strerror();
60#endif
61
62/* Obstack allocation and deallocation routines. */
63#define obstack_chunk_alloc xmalloc
64#define obstack_chunk_free free
65
42/* Obstack allocation and deallocation routines. */
43#define obstack_chunk_alloc xmalloc
44#define obstack_chunk_free free
45
66#if !defined (__STDC__) && !defined (const)
67#define const
68#endif
69
70#ifdef USG
71#define vfork fork
72#endif
73
46#ifdef USG
47#define vfork fork
48#endif
49
74/* Add prototype support. */
75#ifndef PROTO
76#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
77#define PROTO(ARGS) ARGS
78#else
79#define PROTO(ARGS) ()
80#endif
81#endif
82
83#ifndef R_OK
84#define R_OK 4
85#define W_OK 2
86#define X_OK 1
87#endif
88
89#ifndef WIFSIGNALED
90#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
91#endif
92#ifndef WTERMSIG
93#define WTERMSIG(S) ((S) & 0x7f)
94#endif
95#ifndef WIFEXITED
96#define WIFEXITED(S) (((S) & 0xff) == 0)
97#endif
98#ifndef WEXITSTATUS
99#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
100#endif
101
50#ifndef WIFSIGNALED
51#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
52#endif
53#ifndef WTERMSIG
54#define WTERMSIG(S) ((S) & 0x7f)
55#endif
56#ifndef WIFEXITED
57#define WIFEXITED(S) (((S) & 0xff) == 0)
58#endif
59#ifndef WEXITSTATUS
60#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
61#endif
62
102/* On MSDOS, write temp files in current dir
103 because there's no place else we can expect to use. */
104#ifdef __MSDOS__
105#ifndef P_tmpdir
106#define P_tmpdir "./"
107#endif
108#endif
63extern char *make_temp_file PROTO ((char *));
109
110/* On certain systems, we have code that works by scanning the object file
111 directly. But this code uses system-specific header files and library
112 functions, so turn it off in a cross-compiler. Likewise, the names of
64
65/* On certain systems, we have code that works by scanning the object file
66 directly. But this code uses system-specific header files and library
67 functions, so turn it off in a cross-compiler. Likewise, the names of
113 the utilities aren't correct for a cross-compiler; we have to hope that
68 the utilities are not correct for a cross-compiler; we have to hope that
114 cross-versions are in the proper directories. */
115
116#ifdef CROSS_COMPILE
117#undef SUNOS4_SHARED_LIBRARIES
118#undef OBJECT_FORMAT_COFF
119#undef OBJECT_FORMAT_ROSE
120#undef MD_EXEC_PREFIX
121#undef REAL_LD_FILE_NAME
122#undef REAL_NM_FILE_NAME
123#undef REAL_STRIP_FILE_NAME
124#endif
125
69 cross-versions are in the proper directories. */
70
71#ifdef CROSS_COMPILE
72#undef SUNOS4_SHARED_LIBRARIES
73#undef OBJECT_FORMAT_COFF
74#undef OBJECT_FORMAT_ROSE
75#undef MD_EXEC_PREFIX
76#undef REAL_LD_FILE_NAME
77#undef REAL_NM_FILE_NAME
78#undef REAL_STRIP_FILE_NAME
79#endif
80
126/* If we can't use a special method, use the ordinary one:
81/* If we cannot use a special method, use the ordinary one:
127 run nm to find what symbols are present.
128 In a cross-compiler, this means you need a cross nm,
82 run nm to find what symbols are present.
83 In a cross-compiler, this means you need a cross nm,
129 but that isn't quite as unpleasant as special headers. */
84 but that is not quite as unpleasant as special headers. */
130
131#if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
132#define OBJECT_FORMAT_NONE
133#endif
134
135#ifdef OBJECT_FORMAT_COFF
136
137#include <a.out.h>
138#include <ar.h>
139
140#ifdef UMAX
141#include <sgs.h>
142#endif
143
144/* Many versions of ldfcn.h define these. */
145#ifdef FREAD
146#undef FREAD
147#undef FWRITE
148#endif
149
150#include <ldfcn.h>
151
152/* Some systems have an ISCOFF macro, but others do not. In some cases
153 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
154 that either do not have an ISCOFF macro in /usr/include or for those
155 where it is wrong. */
156
157#ifndef MY_ISCOFF
158#define MY_ISCOFF(X) ISCOFF (X)
159#endif
160
85
86#if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
87#define OBJECT_FORMAT_NONE
88#endif
89
90#ifdef OBJECT_FORMAT_COFF
91
92#include <a.out.h>
93#include <ar.h>
94
95#ifdef UMAX
96#include <sgs.h>
97#endif
98
99/* Many versions of ldfcn.h define these. */
100#ifdef FREAD
101#undef FREAD
102#undef FWRITE
103#endif
104
105#include <ldfcn.h>
106
107/* Some systems have an ISCOFF macro, but others do not. In some cases
108 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
109 that either do not have an ISCOFF macro in /usr/include or for those
110 where it is wrong. */
111
112#ifndef MY_ISCOFF
113#define MY_ISCOFF(X) ISCOFF (X)
114#endif
115
161#ifdef XCOFF_DEBUGGING_INFO
162#define XCOFF_SCAN_LIBS
163#endif
164
165#endif /* OBJECT_FORMAT_COFF */
166
167#ifdef OBJECT_FORMAT_ROSE
168
169#ifdef _OSF_SOURCE
170#define USE_MMAP
171#endif
172
173#ifdef USE_MMAP
174#include <sys/mman.h>
175#endif
176
177#include <unistd.h>
178#include <mach_o_format.h>
179#include <mach_o_header.h>
180#include <mach_o_vals.h>
181#include <mach_o_types.h>
182
183#endif /* OBJECT_FORMAT_ROSE */
184
185#ifdef OBJECT_FORMAT_NONE
186
187/* Default flags to pass to nm. */
188#ifndef NM_FLAGS
189#define NM_FLAGS "-p"
190#endif
191
192#endif /* OBJECT_FORMAT_NONE */
193
194/* Some systems use __main in a way incompatible with its use in gcc, in these
195 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
196 give the same symbol without quotes for an alternative entry point. You
197 must define both, or neither. */
198#ifndef NAME__MAIN
199#define NAME__MAIN "__main"
200#define SYMBOL__MAIN __main
201#endif
202
116#endif /* OBJECT_FORMAT_COFF */
117
118#ifdef OBJECT_FORMAT_ROSE
119
120#ifdef _OSF_SOURCE
121#define USE_MMAP
122#endif
123
124#ifdef USE_MMAP
125#include <sys/mman.h>
126#endif
127
128#include <unistd.h>
129#include <mach_o_format.h>
130#include <mach_o_header.h>
131#include <mach_o_vals.h>
132#include <mach_o_types.h>
133
134#endif /* OBJECT_FORMAT_ROSE */
135
136#ifdef OBJECT_FORMAT_NONE
137
138/* Default flags to pass to nm. */
139#ifndef NM_FLAGS
140#define NM_FLAGS "-p"
141#endif
142
143#endif /* OBJECT_FORMAT_NONE */
144
145/* Some systems use __main in a way incompatible with its use in gcc, in these
146 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
147 give the same symbol without quotes for an alternative entry point. You
148 must define both, or neither. */
149#ifndef NAME__MAIN
150#define NAME__MAIN "__main"
151#define SYMBOL__MAIN __main
152#endif
153
203#if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES || defined(XCOFF_SCAN_LIBS)
154#if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
204#define SCAN_LIBRARIES
205#endif
206
207#ifdef USE_COLLECT2
208int do_collecting = 1;
209#else
210int do_collecting = 0;
211#endif
212
155#define SCAN_LIBRARIES
156#endif
157
158#ifdef USE_COLLECT2
159int do_collecting = 1;
160#else
161int do_collecting = 0;
162#endif
163
213/* Linked lists of constructor and destructor names. */
164/* Linked lists of constructor and destructor names. */
214
215struct id
216{
217 struct id *next;
218 int sequence;
219 char name[1];
220};
221
222struct head
223{
224 struct id *first;
225 struct id *last;
226 int number;
227};
228
229/* Enumeration giving which pass this is for scanning the program file. */
230
231enum pass {
232 PASS_FIRST, /* without constructors */
233 PASS_OBJ, /* individual objects */
234 PASS_LIB, /* looking for shared libraries */
235 PASS_SECOND /* with constructors linked in */
236};
237
238#ifndef NO_SYS_SIGLIST
165
166struct id
167{
168 struct id *next;
169 int sequence;
170 char name[1];
171};
172
173struct head
174{
175 struct id *first;
176 struct id *last;
177 int number;
178};
179
180/* Enumeration giving which pass this is for scanning the program file. */
181
182enum pass {
183 PASS_FIRST, /* without constructors */
184 PASS_OBJ, /* individual objects */
185 PASS_LIB, /* looking for shared libraries */
186 PASS_SECOND /* with constructors linked in */
187};
188
189#ifndef NO_SYS_SIGLIST
239#ifndef DONT_DECLARE_SYS_SIGLIST
190#ifndef SYS_SIGLIST_DECLARED
240extern char *sys_siglist[];
241#endif
242#endif
243extern char *version_string;
244
245int vflag; /* true if -v */
246static int rflag; /* true if -r */
247static int strip_flag; /* true if -s */
191extern char *sys_siglist[];
192#endif
193#endif
194extern char *version_string;
195
196int vflag; /* true if -v */
197static int rflag; /* true if -r */
198static int strip_flag; /* true if -s */
199#ifdef COLLECT_EXPORT_LIST
200static int export_flag; /* true if -bE */
201static int aix64_flag; /* true if -b64 */
202#endif
248
249int debug; /* true if -debug */
250
251static int shared_obj; /* true if -shared */
252
203
204int debug; /* true if -debug */
205
206static int shared_obj; /* true if -shared */
207
253static int temp_filename_length; /* Length of temp_filename */
254static char *temp_filename; /* Base of temp filenames */
255static char *c_file; /* <xxx>.c for constructor/destructor list. */
256static char *o_file; /* <xxx>.o for constructor/destructor list. */
257static char *export_file; /* <xxx>.x for AIX export list. */
208static char *c_file; /* <xxx>.c for constructor/destructor list. */
209static char *o_file; /* <xxx>.o for constructor/destructor list. */
210#ifdef COLLECT_EXPORT_LIST
211static char *export_file; /* <xxx>.x for AIX export list. */
212static char *import_file; /* <xxx>.p for AIX import list. */
213#endif
258char *ldout; /* File for ld errors. */
259static char *output_file; /* Output file for ld. */
260static char *nm_file_name; /* pathname of nm */
214char *ldout; /* File for ld errors. */
215static char *output_file; /* Output file for ld. */
216static char *nm_file_name; /* pathname of nm */
217#ifdef LDD_SUFFIX
261static char *ldd_file_name; /* pathname of ldd (or equivalent) */
218static char *ldd_file_name; /* pathname of ldd (or equivalent) */
219#endif
262static char *strip_file_name; /* pathname of strip */
263char *c_file_name; /* pathname of gcc */
264static char *initname, *fininame; /* names of init and fini funcs */
265
266static struct head constructors; /* list of constructors found */
267static struct head destructors; /* list of destructors found */
220static char *strip_file_name; /* pathname of strip */
221char *c_file_name; /* pathname of gcc */
222static char *initname, *fininame; /* names of init and fini funcs */
223
224static struct head constructors; /* list of constructors found */
225static struct head destructors; /* list of destructors found */
226#ifdef COLLECT_EXPORT_LIST
268static struct head exports; /* list of exported symbols */
227static struct head exports; /* list of exported symbols */
228static struct head imports; /* list of imported symbols */
229static struct head undefined; /* list of undefined symbols */
230#endif
231static struct head frame_tables; /* list of frame unwind info tables */
269
270struct obstack temporary_obstack;
271struct obstack permanent_obstack;
272char * temporary_firstobj;
273
274/* Defined in the automatically-generated underscore.c. */
275extern int prepends_underscore;
276
232
233struct obstack temporary_obstack;
234struct obstack permanent_obstack;
235char * temporary_firstobj;
236
237/* Defined in the automatically-generated underscore.c. */
238extern int prepends_underscore;
239
277extern char *getenv ();
278extern char *mktemp ();
279extern FILE *fdopen ();
280
240extern char *mktemp ();
241extern FILE *fdopen ();
242
243#ifndef GET_ENVIRONMENT
244#define GET_ENVIRONMENT(ENV_VALUE,ENV_NAME) ENV_VALUE = getenv (ENV_NAME)
245#endif
246
281/* Structure to hold all the directories in which to search for files to
282 execute. */
283
284struct prefix_list
285{
247/* Structure to hold all the directories in which to search for files to
248 execute. */
249
250struct prefix_list
251{
286 char *prefix; /* String to prepend to the path. */
287 struct prefix_list *next; /* Next in linked list. */
252 char *prefix; /* String to prepend to the path. */
253 struct prefix_list *next; /* Next in linked list. */
288};
289
290struct path_prefix
291{
292 struct prefix_list *plist; /* List of prefixes to try */
293 int max_len; /* Max length of a prefix in PLIST */
294 char *name; /* Name of this list (used in config stuff) */
295};
296
254};
255
256struct path_prefix
257{
258 struct prefix_list *plist; /* List of prefixes to try */
259 int max_len; /* Max length of a prefix in PLIST */
260 char *name; /* Name of this list (used in config stuff) */
261};
262
297void collect_exit PROTO((int));
298void collect_execute PROTO((char *, char **, char *));
299void dump_file PROTO((char *));
263#ifdef COLLECT_EXPORT_LIST
264/* Lists to keep libraries to be scanned for global constructors/destructors. */
265static struct head libs; /* list of libraries */
266static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
267static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
268static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
269 &libpath_lib_dirs, NULL};
270static char *libexts[3] = {"a", "so", NULL}; /* possible library extentions */
271#endif
272
273static char *my_strerror PROTO((int));
300static void handler PROTO((int));
301static int is_ctor_dtor PROTO((char *));
274static void handler PROTO((int));
275static int is_ctor_dtor PROTO((char *));
302static void choose_temp_base PROTO((void));
303static int is_in_prefix_list PROTO((struct path_prefix *, char *, int));
304static char *find_a_file PROTO((struct path_prefix *, char *));
305static void add_prefix PROTO((struct path_prefix *, char *));
306static void prefix_from_env PROTO((char *, struct path_prefix *));
307static void prefix_from_string PROTO((char *, struct path_prefix *));
308static void do_wait PROTO((char *));
309static void fork_execute PROTO((char *, char **));
310static void maybe_unlink PROTO((char *));
311static void add_to_list PROTO((struct head *, char *));
312static void write_list PROTO((FILE *, char *, struct id *));
276static char *find_a_file PROTO((struct path_prefix *, char *));
277static void add_prefix PROTO((struct path_prefix *, char *));
278static void prefix_from_env PROTO((char *, struct path_prefix *));
279static void prefix_from_string PROTO((char *, struct path_prefix *));
280static void do_wait PROTO((char *));
281static void fork_execute PROTO((char *, char **));
282static void maybe_unlink PROTO((char *));
283static void add_to_list PROTO((struct head *, char *));
284static void write_list PROTO((FILE *, char *, struct id *));
285#ifdef COLLECT_EXPORT_LIST
286static void dump_list PROTO((FILE *, char *, struct id *));
287#endif
288#if 0
289static void dump_prefix_list PROTO((FILE *, char *, struct prefix_list *));
290#endif
313static void write_list_with_asm PROTO((FILE *, char *, struct id *));
314static void write_c_file PROTO((FILE *, char *));
291static void write_list_with_asm PROTO((FILE *, char *, struct id *));
292static void write_c_file PROTO((FILE *, char *));
315static void write_export_file PROTO((FILE *));
316static void scan_prog_file PROTO((char *, enum pass));
293static void scan_prog_file PROTO((char *, enum pass));
294#ifdef SCAN_LIBRARIES
317static void scan_libraries PROTO((char *));
295static void scan_libraries PROTO((char *));
296#endif
297#ifdef COLLECT_EXPORT_LIST
298static int is_in_list PROTO((char *, struct id *));
299static void write_export_file PROTO((FILE *));
300static void write_import_file PROTO((FILE *));
301static char *resolve_lib_name PROTO((char *));
302static int use_import_list PROTO((char *));
303static int ignore_library PROTO((char *));
304#endif
318
319char *xcalloc ();
320char *xmalloc ();
321
305
306char *xcalloc ();
307char *xmalloc ();
308
322extern char *index ();
323extern char *rindex ();
324extern void free ();
325
326#ifdef NO_DUP2
327int
328dup2 (oldfd, newfd)
329 int oldfd;
330 int newfd;
331{
332 int fdtmp[256];
333 int fdx = 0;
334 int fd;
335
336 if (oldfd == newfd)
337 return oldfd;
338 close (newfd);
339 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
340 fdtmp[fdx++] = fd;
341 while (fdx > 0)
342 close (fdtmp[--fdx]);
343
344 return fd;
345}
346#endif
347
309
310#ifdef NO_DUP2
311int
312dup2 (oldfd, newfd)
313 int oldfd;
314 int newfd;
315{
316 int fdtmp[256];
317 int fdx = 0;
318 int fd;
319
320 if (oldfd == newfd)
321 return oldfd;
322 close (newfd);
323 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
324 fdtmp[fdx++] = fd;
325 while (fdx > 0)
326 close (fdtmp[--fdx]);
327
328 return fd;
329}
330#endif
331
348char *
332static char *
349my_strerror (e)
350 int e;
351{
352
353#ifdef HAVE_STRERROR
354 return strerror (e);
355
356#else
357
358 static char buffer[30];
359 if (!e)
360 return "";
361
362 if (e > 0 && e < sys_nerr)
363 return sys_errlist[e];
364
365 sprintf (buffer, "Unknown error %d", e);
366 return buffer;
367#endif
368}
369
370/* Delete tempfiles and exit function. */
371
372void
373collect_exit (status)
374 int status;
375{
376 if (c_file != 0 && c_file[0])
377 maybe_unlink (c_file);
378
379 if (o_file != 0 && o_file[0])
380 maybe_unlink (o_file);
381
333my_strerror (e)
334 int e;
335{
336
337#ifdef HAVE_STRERROR
338 return strerror (e);
339
340#else
341
342 static char buffer[30];
343 if (!e)
344 return "";
345
346 if (e > 0 && e < sys_nerr)
347 return sys_errlist[e];
348
349 sprintf (buffer, "Unknown error %d", e);
350 return buffer;
351#endif
352}
353
354/* Delete tempfiles and exit function. */
355
356void
357collect_exit (status)
358 int status;
359{
360 if (c_file != 0 && c_file[0])
361 maybe_unlink (c_file);
362
363 if (o_file != 0 && o_file[0])
364 maybe_unlink (o_file);
365
366#ifdef COLLECT_EXPORT_LIST
382 if (export_file != 0 && export_file[0])
383 maybe_unlink (export_file);
384
367 if (export_file != 0 && export_file[0])
368 maybe_unlink (export_file);
369
370 if (import_file != 0 && import_file[0])
371 maybe_unlink (import_file);
372#endif
373
385 if (ldout != 0 && ldout[0])
386 {
387 dump_file (ldout);
388 maybe_unlink (ldout);
389 }
390
391 if (status != 0 && output_file != 0 && output_file[0])
392 maybe_unlink (output_file);
393
394 exit (status);
395}
396
397
374 if (ldout != 0 && ldout[0])
375 {
376 dump_file (ldout);
377 maybe_unlink (ldout);
378 }
379
380 if (status != 0 && output_file != 0 && output_file[0])
381 maybe_unlink (output_file);
382
383 exit (status);
384}
385
386
398/* Die when sys call fails. */
387/* Die when sys call fails. */
399
400void
401fatal_perror (string, arg1, arg2, arg3)
402 char *string, *arg1, *arg2, *arg3;
403{
404 int e = errno;
405
406 fprintf (stderr, "collect2: ");
407 fprintf (stderr, string, arg1, arg2, arg3);
408 fprintf (stderr, ": %s\n", my_strerror (e));
388
389void
390fatal_perror (string, arg1, arg2, arg3)
391 char *string, *arg1, *arg2, *arg3;
392{
393 int e = errno;
394
395 fprintf (stderr, "collect2: ");
396 fprintf (stderr, string, arg1, arg2, arg3);
397 fprintf (stderr, ": %s\n", my_strerror (e));
409 collect_exit (1);
398 collect_exit (FATAL_EXIT_CODE);
410}
411
399}
400
412/* Just die. */
401/* Just die. */
413
414void
415fatal (string, arg1, arg2, arg3)
416 char *string, *arg1, *arg2, *arg3;
417{
418 fprintf (stderr, "collect2: ");
419 fprintf (stderr, string, arg1, arg2, arg3);
420 fprintf (stderr, "\n");
402
403void
404fatal (string, arg1, arg2, arg3)
405 char *string, *arg1, *arg2, *arg3;
406{
407 fprintf (stderr, "collect2: ");
408 fprintf (stderr, string, arg1, arg2, arg3);
409 fprintf (stderr, "\n");
421 collect_exit (1);
410 collect_exit (FATAL_EXIT_CODE);
422}
423
424/* Write error message. */
425
426void
427error (string, arg1, arg2, arg3, arg4)
428 char *string, *arg1, *arg2, *arg3, *arg4;
429{
430 fprintf (stderr, "collect2: ");
431 fprintf (stderr, string, arg1, arg2, arg3, arg4);
432 fprintf (stderr, "\n");
433}
434
435/* In case obstack is linked in, and abort is defined to fancy_abort,
436 provide a default entry. */
437
438void
439fancy_abort ()
440{
441 fatal ("internal error");
442}
443
444
445static void
446handler (signo)
447 int signo;
448{
449 if (c_file != 0 && c_file[0])
450 maybe_unlink (c_file);
451
452 if (o_file != 0 && o_file[0])
453 maybe_unlink (o_file);
454
455 if (ldout != 0 && ldout[0])
456 maybe_unlink (ldout);
457
411}
412
413/* Write error message. */
414
415void
416error (string, arg1, arg2, arg3, arg4)
417 char *string, *arg1, *arg2, *arg3, *arg4;
418{
419 fprintf (stderr, "collect2: ");
420 fprintf (stderr, string, arg1, arg2, arg3, arg4);
421 fprintf (stderr, "\n");
422}
423
424/* In case obstack is linked in, and abort is defined to fancy_abort,
425 provide a default entry. */
426
427void
428fancy_abort ()
429{
430 fatal ("internal error");
431}
432
433
434static void
435handler (signo)
436 int signo;
437{
438 if (c_file != 0 && c_file[0])
439 maybe_unlink (c_file);
440
441 if (o_file != 0 && o_file[0])
442 maybe_unlink (o_file);
443
444 if (ldout != 0 && ldout[0])
445 maybe_unlink (ldout);
446
447#ifdef COLLECT_EXPORT_LIST
448 if (export_file != 0 && export_file[0])
449 maybe_unlink (export_file);
450
451 if (import_file != 0 && import_file[0])
452 maybe_unlink (import_file);
453#endif
454
458 signal (signo, SIG_DFL);
459 kill (getpid (), signo);
460}
461
462
463char *
464xcalloc (size1, size2)
465 int size1, size2;
466{
467 char *ptr = (char *) calloc (size1, size2);
468 if (ptr)
469 return ptr;
470
471 fatal ("out of memory");
455 signal (signo, SIG_DFL);
456 kill (getpid (), signo);
457}
458
459
460char *
461xcalloc (size1, size2)
462 int size1, size2;
463{
464 char *ptr = (char *) calloc (size1, size2);
465 if (ptr)
466 return ptr;
467
468 fatal ("out of memory");
472 return (char *)0;
469 return (char *) 0;
473}
474
475char *
476xmalloc (size)
477 unsigned size;
478{
479 char *ptr = (char *) malloc (size);
480 if (ptr)
481 return ptr;
482
483 fatal ("out of memory");
470}
471
472char *
473xmalloc (size)
474 unsigned size;
475{
476 char *ptr = (char *) malloc (size);
477 if (ptr)
478 return ptr;
479
480 fatal ("out of memory");
484 return (char *)0;
481 return (char *) 0;
485}
486
487char *
488xrealloc (ptr, size)
489 char *ptr;
490 unsigned size;
491{
492 register char *value = (char *) realloc (ptr, size);
493 if (value == 0)
494 fatal ("virtual memory exhausted");
495 return value;
496}
497
498int
499file_exists (name)
500 char *name;
501{
502 return access (name, R_OK) == 0;
503}
504
505/* Make a copy of a string INPUT with size SIZE. */
506
507char *
508savestring (input, size)
509 char *input;
510 int size;
511{
512 char *output = (char *) xmalloc (size + 1);
513 bcopy (input, output, size);
514 output[size] = 0;
515 return output;
516}
482}
483
484char *
485xrealloc (ptr, size)
486 char *ptr;
487 unsigned size;
488{
489 register char *value = (char *) realloc (ptr, size);
490 if (value == 0)
491 fatal ("virtual memory exhausted");
492 return value;
493}
494
495int
496file_exists (name)
497 char *name;
498{
499 return access (name, R_OK) == 0;
500}
501
502/* Make a copy of a string INPUT with size SIZE. */
503
504char *
505savestring (input, size)
506 char *input;
507 int size;
508{
509 char *output = (char *) xmalloc (size + 1);
510 bcopy (input, output, size);
511 output[size] = 0;
512 return output;
513}
514
515/* Parse a reasonable subset of shell quoting syntax. */
516
517static char *
518extract_string (pp)
519 char **pp;
520{
521 char *p = *pp;
522 int backquote = 0;
523 int inside = 0;
524
525 for (;;)
526 {
527 char c = *p;
528 if (c == '\0')
529 break;
530 ++p;
531 if (backquote)
532 obstack_1grow (&temporary_obstack, c);
533 else if (! inside && c == ' ')
534 break;
535 else if (! inside && c == '\\')
536 backquote = 1;
537 else if (c == '\'')
538 inside = !inside;
539 else
540 obstack_1grow (&temporary_obstack, c);
541 }
542
543 obstack_1grow (&temporary_obstack, '\0');
544 *pp = p;
545 return obstack_finish (&temporary_obstack);
546}
517
518void
519dump_file (name)
520 char *name;
521{
522 FILE *stream = fopen (name, "r");
523 int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
524
525 if (stream == 0)
526 return;
527 while (1)
528 {
529 int c;
530 while (c = getc (stream),
547
548void
549dump_file (name)
550 char *name;
551{
552 FILE *stream = fopen (name, "r");
553 int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
554
555 if (stream == 0)
556 return;
557 while (1)
558 {
559 int c;
560 while (c = getc (stream),
531 c != EOF && (isalnum (c) || c == '_' || c == '$' || c == '.'))
561 c != EOF && (ISALNUM (c) || c == '_' || c == '$' || c == '.'))
532 obstack_1grow (&temporary_obstack, c);
533 if (obstack_object_size (&temporary_obstack) > 0)
534 {
535 char *word, *p, *result;
536 obstack_1grow (&temporary_obstack, '\0');
537 word = obstack_finish (&temporary_obstack);
538
539 if (*word == '.')
540 ++word, putc ('.', stderr);
541 p = word;
542 if (*p == '_' && prepends_underscore)
543 ++p;
544
545 if (no_demangle)
546 result = 0;
547 else
548 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
549
550 if (result)
551 {
552 int diff;
553 fputs (result, stderr);
554
555 diff = strlen (word) - strlen (result);
556 while (diff > 0)
557 --diff, putc (' ', stderr);
558 while (diff < 0 && c == ' ')
559 ++diff, c = getc (stream);
560
561 free (result);
562 }
563 else
564 fputs (word, stderr);
565
566 fflush (stderr);
567 obstack_free (&temporary_obstack, temporary_firstobj);
568 }
569 if (c == EOF)
570 break;
571 putc (c, stderr);
572 }
562 obstack_1grow (&temporary_obstack, c);
563 if (obstack_object_size (&temporary_obstack) > 0)
564 {
565 char *word, *p, *result;
566 obstack_1grow (&temporary_obstack, '\0');
567 word = obstack_finish (&temporary_obstack);
568
569 if (*word == '.')
570 ++word, putc ('.', stderr);
571 p = word;
572 if (*p == '_' && prepends_underscore)
573 ++p;
574
575 if (no_demangle)
576 result = 0;
577 else
578 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
579
580 if (result)
581 {
582 int diff;
583 fputs (result, stderr);
584
585 diff = strlen (word) - strlen (result);
586 while (diff > 0)
587 --diff, putc (' ', stderr);
588 while (diff < 0 && c == ' ')
589 ++diff, c = getc (stream);
590
591 free (result);
592 }
593 else
594 fputs (word, stderr);
595
596 fflush (stderr);
597 obstack_free (&temporary_obstack, temporary_firstobj);
598 }
599 if (c == EOF)
600 break;
601 putc (c, stderr);
602 }
603 fclose (stream);
573}
574
575/* Decide whether the given symbol is:
576 a constructor (1), a destructor (2), or neither (0). */
577
578static int
579is_ctor_dtor (s)
580 char *s;
581{
582 struct names { char *name; int len; int ret; int two_underscores; };
583
584 register struct names *p;
585 register int ch;
586 register char *orig_s = s;
587
588 static struct names special[] = {
589#ifdef NO_DOLLAR_IN_LABEL
590#ifdef NO_DOT_IN_LABEL
591 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
592 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
604}
605
606/* Decide whether the given symbol is:
607 a constructor (1), a destructor (2), or neither (0). */
608
609static int
610is_ctor_dtor (s)
611 char *s;
612{
613 struct names { char *name; int len; int ret; int two_underscores; };
614
615 register struct names *p;
616 register int ch;
617 register char *orig_s = s;
618
619 static struct names special[] = {
620#ifdef NO_DOLLAR_IN_LABEL
621#ifdef NO_DOT_IN_LABEL
622 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
623 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
624 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
593#else
594 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
595 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
625#else
626 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
627 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
628 { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },
596#endif
597#else
598 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
599 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
629#endif
630#else
631 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
632 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
633 { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },
600#endif
601 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
602 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
634#endif
635 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
636 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
603#ifdef CFRONT_LOSSAGE /* Don't collect cfront initialization functions.
637#ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
604 cfront has its own linker procedure to collect them;
605 if collect2 gets them too, they get collected twice
606 when the cfront procedure is run and the compiler used
607 for linking happens to be GCC. */
608 { "sti__", sizeof ("sti__")-1, 1, 1 },
609 { "std__", sizeof ("std__")-1, 2, 1 },
610#endif /* CFRONT_LOSSAGE */
611 { NULL, 0, 0, 0 }
612 };
613
614 while ((ch = *s) == '_')
615 ++s;
616
617 if (s == orig_s)
618 return 0;
619
620 for (p = &special[0]; p->len > 0; p++)
621 {
622 if (ch == p->name[0]
623 && (!p->two_underscores || ((s - orig_s) >= 2))
624 && strncmp(s, p->name, p->len) == 0)
625 {
626 return p->ret;
627 }
628 }
629 return 0;
630}
638 cfront has its own linker procedure to collect them;
639 if collect2 gets them too, they get collected twice
640 when the cfront procedure is run and the compiler used
641 for linking happens to be GCC. */
642 { "sti__", sizeof ("sti__")-1, 1, 1 },
643 { "std__", sizeof ("std__")-1, 2, 1 },
644#endif /* CFRONT_LOSSAGE */
645 { NULL, 0, 0, 0 }
646 };
647
648 while ((ch = *s) == '_')
649 ++s;
650
651 if (s == orig_s)
652 return 0;
653
654 for (p = &special[0]; p->len > 0; p++)
655 {
656 if (ch == p->name[0]
657 && (!p->two_underscores || ((s - orig_s) >= 2))
658 && strncmp(s, p->name, p->len) == 0)
659 {
660 return p->ret;
661 }
662 }
663 return 0;
664}
631
632
665
633/* Compute a string to use as the base of all temporary file names.
634 It is substituted for %g. */
635
636static void
637choose_temp_base ()
638{
639 char *base = getenv ("TMPDIR");
640 int len;
641
642 if (base == (char *)0)
643 {
644#ifdef P_tmpdir
645 if (access (P_tmpdir, R_OK | W_OK) == 0)
646 base = P_tmpdir;
647#endif
648 if (base == (char *)0)
649 {
650 if (access ("/usr/tmp", R_OK | W_OK) == 0)
651 base = "/usr/tmp/";
652 else
653 base = "/tmp/";
654 }
655 }
656
657 len = strlen (base);
658 temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
659 strcpy (temp_filename, base);
660 if (len > 0 && temp_filename[len-1] != '/')
661 temp_filename[len++] = '/';
662 strcpy (temp_filename + len, "ccXXXXXX");
663
664 mktemp (temp_filename);
665 temp_filename_length = strlen (temp_filename);
666}
667
668/* Routine to add variables to the environment. */
669
670#ifndef HAVE_PUTENV
671
672int
673putenv (str)
674 char *str;
675{
676#ifndef VMS /* nor about VMS */
677
678 extern char **environ;
679 char **old_environ = environ;
680 char **envp;
681 int num_envs = 0;
682 int name_len = 1;
683 char *p = str;
684 int ch;
685
686 while ((ch = *p++) != '\0' && ch != '=')
687 name_len++;
688
689 if (!ch)
690 abort ();
691
692 /* Search for replacing an existing environment variable, and
693 count the number of total environment variables. */
694 for (envp = old_environ; *envp; envp++)
695 {
696 num_envs++;
697 if (!strncmp (str, *envp, name_len))
698 {
699 *envp = str;
700 return 0;
701 }
702 }
703
704 /* Add a new environment variable */
705 environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
706 *environ = str;
707 bcopy ((char *) old_environ, (char *) (environ + 1),
708 sizeof (char *) * (num_envs+1));
709
710 return 0;
711#endif /* VMS */
712}
713
714#endif /* HAVE_PUTENV */
715
716/* By default, colon separates directories in a path. */
717#ifndef PATH_SEPARATOR
718#define PATH_SEPARATOR ':'
719#endif
720
721/* We maintain two prefix lists: one from COMPILER_PATH environment variable
722 and one from the PATH variable. */
723
724static struct path_prefix cpath, path;
725
726#ifdef CROSS_COMPILE
727/* This is the name of the target machine. We use it to form the name
728 of the files to execute. */
729
730static char *target_machine = TARGET_MACHINE;
731#endif
732
666/* Routine to add variables to the environment. */
667
668#ifndef HAVE_PUTENV
669
670int
671putenv (str)
672 char *str;
673{
674#ifndef VMS /* nor about VMS */
675
676 extern char **environ;
677 char **old_environ = environ;
678 char **envp;
679 int num_envs = 0;
680 int name_len = 1;
681 char *p = str;
682 int ch;
683
684 while ((ch = *p++) != '\0' && ch != '=')
685 name_len++;
686
687 if (!ch)
688 abort ();
689
690 /* Search for replacing an existing environment variable, and
691 count the number of total environment variables. */
692 for (envp = old_environ; *envp; envp++)
693 {
694 num_envs++;
695 if (!strncmp (str, *envp, name_len))
696 {
697 *envp = str;
698 return 0;
699 }
700 }
701
702 /* Add a new environment variable */
703 environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
704 *environ = str;
705 bcopy ((char *) old_environ, (char *) (environ + 1),
706 sizeof (char *) * (num_envs+1));
707
708 return 0;
709#endif /* VMS */
710}
711
712#endif /* HAVE_PUTENV */
713
714/* By default, colon separates directories in a path. */
715#ifndef PATH_SEPARATOR
716#define PATH_SEPARATOR ':'
717#endif
718
719/* We maintain two prefix lists: one from COMPILER_PATH environment variable
720 and one from the PATH variable. */
721
722static struct path_prefix cpath, path;
723
724#ifdef CROSS_COMPILE
725/* This is the name of the target machine. We use it to form the name
726 of the files to execute. */
727
728static char *target_machine = TARGET_MACHINE;
729#endif
730
733/* Names under which we were executed. Never return one of those files in our
734 searches. */
735
736static struct path_prefix our_file_names;
737
738/* Determine if STRING is in PPREFIX.
739
740 This utility is currently only used to look up file names. Prefix lists
741 record directory names. This matters to us because the latter has a
742 trailing slash, so I've added a flag to handle both. */
743
744static int
745is_in_prefix_list (pprefix, string, filep)
746 struct path_prefix *pprefix;
747 char *string;
748 int filep;
749{
750 struct prefix_list *pl;
751
752 if (filep)
753 {
754 int len = strlen (string);
755
756 for (pl = pprefix->plist; pl; pl = pl->next)
757 {
758 if (strncmp (pl->prefix, string, len) == 0
759 && strcmp (pl->prefix + len, "/") == 0)
760 return 1;
761 }
762 }
763 else
764 {
765 for (pl = pprefix->plist; pl; pl = pl->next)
766 {
767 if (strcmp (pl->prefix, string) == 0)
768 return 1;
769 }
770 }
771
772 return 0;
773}
774
775/* Search for NAME using prefix list PPREFIX. We only look for executable
776 files.
777
731/* Search for NAME using prefix list PPREFIX. We only look for executable
732 files.
733
778 Return 0 if not found, otherwise return its name, allocated with malloc. */
734 Return 0 if not found, otherwise return its name, allocated with malloc. */
779
780static char *
781find_a_file (pprefix, name)
782 struct path_prefix *pprefix;
783 char *name;
784{
785 char *temp;
786 struct prefix_list *pl;
787 int len = pprefix->max_len + strlen (name) + 1;
788
735
736static char *
737find_a_file (pprefix, name)
738 struct path_prefix *pprefix;
739 char *name;
740{
741 char *temp;
742 struct prefix_list *pl;
743 int len = pprefix->max_len + strlen (name) + 1;
744
745 if (debug)
746 fprintf (stderr, "Looking for '%s'\n", name);
747
789#ifdef EXECUTABLE_SUFFIX
790 len += strlen (EXECUTABLE_SUFFIX);
791#endif
792
793 temp = xmalloc (len);
794
795 /* Determine the filename to execute (special case for absolute paths). */
796
748#ifdef EXECUTABLE_SUFFIX
749 len += strlen (EXECUTABLE_SUFFIX);
750#endif
751
752 temp = xmalloc (len);
753
754 /* Determine the filename to execute (special case for absolute paths). */
755
797 if (*name == '/')
756 if (*name == '/'
757#ifdef DIR_SEPARATOR
758 || (DIR_SEPARATOR == '\\' && name[1] == ':'
759 && (name[2] == DIR_SEPARATOR || name[2] == '/'))
760#endif
761 )
798 {
799 if (access (name, X_OK) == 0)
800 {
801 strcpy (temp, name);
762 {
763 if (access (name, X_OK) == 0)
764 {
765 strcpy (temp, name);
766
767 if (debug)
768 fprintf (stderr, " - found: absolute path\n");
769
802 return temp;
803 }
770 return temp;
771 }
772
773 if (debug)
774 fprintf (stderr, " - failed to locate using absolute path\n");
804 }
805 else
806 for (pl = pprefix->plist; pl; pl = pl->next)
807 {
808 strcpy (temp, pl->prefix);
809 strcat (temp, name);
775 }
776 else
777 for (pl = pprefix->plist; pl; pl = pl->next)
778 {
779 strcpy (temp, pl->prefix);
780 strcat (temp, name);
810 if (! is_in_prefix_list (&our_file_names, temp, 1)
811 /* This is a kludge, but there seems no way around it. */
812 && strcmp (temp, "./ld") != 0
813 && access (temp, X_OK) == 0)
781
782 if (access (temp, X_OK) == 0)
814 return temp;
815
816#ifdef EXECUTABLE_SUFFIX
817 /* Some systems have a suffix for executable files.
818 So try appending that. */
819 strcat (temp, EXECUTABLE_SUFFIX);
783 return temp;
784
785#ifdef EXECUTABLE_SUFFIX
786 /* Some systems have a suffix for executable files.
787 So try appending that. */
788 strcat (temp, EXECUTABLE_SUFFIX);
820 if (! is_in_prefix_list (&our_file_names, temp, 1)
821 && access (temp, X_OK) == 0)
789
790 if (access (temp, X_OK) == 0)
822 return temp;
823#endif
824 }
825
791 return temp;
792#endif
793 }
794
795 if (debug && pprefix->plist == NULL)
796 fprintf (stderr, " - failed: no entries in prefix list\n");
797
826 free (temp);
827 return 0;
828}
829
830/* Add an entry for PREFIX to prefix list PPREFIX. */
831
832static void
833add_prefix (pprefix, prefix)
834 struct path_prefix *pprefix;
835 char *prefix;
836{
837 struct prefix_list *pl, **prev;
838 int len;
839
840 if (pprefix->plist)
841 {
842 for (pl = pprefix->plist; pl->next; pl = pl->next)
843 ;
844 prev = &pl->next;
845 }
846 else
847 prev = &pprefix->plist;
848
849 /* Keep track of the longest prefix */
850
851 len = strlen (prefix);
852 if (len > pprefix->max_len)
853 pprefix->max_len = len;
854
855 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
856 pl->prefix = savestring (prefix, len);
857
858 if (*prev)
859 pl->next = *prev;
860 else
861 pl->next = (struct prefix_list *) 0;
862 *prev = pl;
863}
864
865/* Take the value of the environment variable ENV, break it into a path, and
866 add of the entries to PPREFIX. */
867
868static void
869prefix_from_env (env, pprefix)
870 char *env;
871 struct path_prefix *pprefix;
872{
798 free (temp);
799 return 0;
800}
801
802/* Add an entry for PREFIX to prefix list PPREFIX. */
803
804static void
805add_prefix (pprefix, prefix)
806 struct path_prefix *pprefix;
807 char *prefix;
808{
809 struct prefix_list *pl, **prev;
810 int len;
811
812 if (pprefix->plist)
813 {
814 for (pl = pprefix->plist; pl->next; pl = pl->next)
815 ;
816 prev = &pl->next;
817 }
818 else
819 prev = &pprefix->plist;
820
821 /* Keep track of the longest prefix */
822
823 len = strlen (prefix);
824 if (len > pprefix->max_len)
825 pprefix->max_len = len;
826
827 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
828 pl->prefix = savestring (prefix, len);
829
830 if (*prev)
831 pl->next = *prev;
832 else
833 pl->next = (struct prefix_list *) 0;
834 *prev = pl;
835}
836
837/* Take the value of the environment variable ENV, break it into a path, and
838 add of the entries to PPREFIX. */
839
840static void
841prefix_from_env (env, pprefix)
842 char *env;
843 struct path_prefix *pprefix;
844{
873 char *p = getenv (env);
845 char *p;
846 GET_ENVIRONMENT (p, env);
874
875 if (p)
876 prefix_from_string (p, pprefix);
877}
878
879static void
880prefix_from_string (p, pprefix)
881 char *p;
882 struct path_prefix *pprefix;
883{
884 char *startp, *endp;
885 char *nstore = (char *) xmalloc (strlen (p) + 3);
886
847
848 if (p)
849 prefix_from_string (p, pprefix);
850}
851
852static void
853prefix_from_string (p, pprefix)
854 char *p;
855 struct path_prefix *pprefix;
856{
857 char *startp, *endp;
858 char *nstore = (char *) xmalloc (strlen (p) + 3);
859
860 if (debug)
861 fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
862
887 startp = endp = p;
888 while (1)
889 {
890 if (*endp == PATH_SEPARATOR || *endp == 0)
891 {
892 strncpy (nstore, startp, endp-startp);
893 if (endp == startp)
894 {
895 strcpy (nstore, "./");
896 }
897 else if (endp[-1] != '/')
898 {
899 nstore[endp-startp] = '/';
900 nstore[endp-startp+1] = 0;
901 }
902 else
903 nstore[endp-startp] = 0;
904
863 startp = endp = p;
864 while (1)
865 {
866 if (*endp == PATH_SEPARATOR || *endp == 0)
867 {
868 strncpy (nstore, startp, endp-startp);
869 if (endp == startp)
870 {
871 strcpy (nstore, "./");
872 }
873 else if (endp[-1] != '/')
874 {
875 nstore[endp-startp] = '/';
876 nstore[endp-startp+1] = 0;
877 }
878 else
879 nstore[endp-startp] = 0;
880
881 if (debug)
882 fprintf (stderr, " - add prefix: %s\n", nstore);
883
905 add_prefix (pprefix, nstore);
906 if (*endp == 0)
907 break;
908 endp = startp = endp + 1;
909 }
910 else
911 endp++;
912 }
913}
914
884 add_prefix (pprefix, nstore);
885 if (*endp == 0)
886 break;
887 endp = startp = endp + 1;
888 }
889 else
890 endp++;
891 }
892}
893
915/* Main program. */
894/* Main program. */
916
917int
918main (argc, argv)
919 int argc;
920 char *argv[];
921{
922 char *ld_suffix = "ld";
923 char *full_ld_suffix = ld_suffix;
924 char *real_ld_suffix = "real-ld";
895
896int
897main (argc, argv)
898 int argc;
899 char *argv[];
900{
901 char *ld_suffix = "ld";
902 char *full_ld_suffix = ld_suffix;
903 char *real_ld_suffix = "real-ld";
925 char *full_real_ld_suffix = real_ld_suffix;
926 char *collect_ld_suffix = "collect-ld";
927 char *nm_suffix = "nm";
928 char *full_nm_suffix = nm_suffix;
929 char *gnm_suffix = "gnm";
930 char *full_gnm_suffix = gnm_suffix;
931#ifdef LDD_SUFFIX
932 char *ldd_suffix = LDD_SUFFIX;
933 char *full_ldd_suffix = ldd_suffix;
934#endif
935 char *strip_suffix = "strip";
936 char *full_strip_suffix = strip_suffix;
937 char *gstrip_suffix = "gstrip";
938 char *full_gstrip_suffix = gstrip_suffix;
939 char *arg;
904 char *collect_ld_suffix = "collect-ld";
905 char *nm_suffix = "nm";
906 char *full_nm_suffix = nm_suffix;
907 char *gnm_suffix = "gnm";
908 char *full_gnm_suffix = gnm_suffix;
909#ifdef LDD_SUFFIX
910 char *ldd_suffix = LDD_SUFFIX;
911 char *full_ldd_suffix = ldd_suffix;
912#endif
913 char *strip_suffix = "strip";
914 char *full_strip_suffix = strip_suffix;
915 char *gstrip_suffix = "gstrip";
916 char *full_gstrip_suffix = gstrip_suffix;
917 char *arg;
940 FILE *outf, *exportf;
918 FILE *outf;
919#ifdef COLLECT_EXPORT_LIST
920 FILE *exportf;
921 FILE *importf;
922#endif
941 char *ld_file_name;
923 char *ld_file_name;
942 char *collect_name;
943 char *collect_names;
944 char *p;
945 char **c_argv;
946 char **c_ptr;
947 char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+3);
948 char **ld1 = ld1_argv;
949 char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+6);
950 char **ld2 = ld2_argv;
951 char **object_lst = (char **) xcalloc (sizeof (char *), argc);
952 char **object = object_lst;
953 int first_file;
924 char *p;
925 char **c_argv;
926 char **c_ptr;
927 char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+3);
928 char **ld1 = ld1_argv;
929 char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+6);
930 char **ld2 = ld2_argv;
931 char **object_lst = (char **) xcalloc (sizeof (char *), argc);
932 char **object = object_lst;
933 int first_file;
954 int num_c_args = argc+7;
934 int num_c_args = argc+9;
955
956#ifdef DEBUG
957 debug = 1;
935
936#ifdef DEBUG
937 debug = 1;
958 vflag = 1;
959#endif
960
938#endif
939
940 /* Parse command line early for instances of -debug. This allows
941 the debug flag to be set before functions like find_a_file()
942 are called. */
943 {
944 int i;
945
946 for (i = 1; argv[i] != NULL; i ++)
947 if (! strcmp (argv[i], "-debug"))
948 debug = 1;
949 vflag = debug;
950 }
951
952#ifndef DEFAULT_A_OUT_NAME
961 output_file = "a.out";
953 output_file = "a.out";
954#else
955 output_file = DEFAULT_A_OUT_NAME;
956#endif
962
963 obstack_begin (&temporary_obstack, 0);
964 obstack_begin (&permanent_obstack, 0);
965 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
957
958 obstack_begin (&temporary_obstack, 0);
959 obstack_begin (&permanent_obstack, 0);
960 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
961
966 current_demangling_style = gnu_demangling;
962 current_demangling_style = gnu_demangling;
963 p = getenv ("COLLECT_GCC_OPTIONS");
964 while (p && *p)
965 {
966 char *q = extract_string (&p);
967 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
968 num_c_args++;
969 }
970 obstack_free (&temporary_obstack, temporary_firstobj);
971 ++num_c_args;
967
972
968 /* We must check that we do not call ourselves in an infinite
969 recursion loop. We append the name used for us to the COLLECT_NAMES
970 environment variable.
971
972 In practice, collect will rarely invoke itself. This can happen now
973 that we are no longer called gld. A perfect example is when running
974 gcc in a build directory that has been installed. When looking for
975 ld's, we'll find our installed version and believe that's the real ld. */
976
977 /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the
978 previous version of collect (the one that used COLLECT_NAME and only
979 handled two levels of recursion). If we don't we may mutually recurse
980 forever. This can happen (I think) when bootstrapping the old version
981 and a new one is installed (rare, but we should handle it).
982 ??? Hopefully references to COLLECT_NAME can be removed at some point. */
983
984 collect_name = (char *) getenv ("COLLECT_NAME");
985 collect_names = (char *) getenv ("COLLECT_NAMES");
986
987 p = (char *) xmalloc (strlen ("COLLECT_NAMES=")
988 + (collect_name ? strlen (collect_name) + 1 : 0)
989 + (collect_names ? strlen (collect_names) + 1 : 0)
990 + strlen (argv[0]) + 1);
991 strcpy (p, "COLLECT_NAMES=");
992 if (collect_name != 0)
993 sprintf (p + strlen (p), "%s%c", collect_name, PATH_SEPARATOR);
994 if (collect_names != 0)
995 sprintf (p + strlen (p), "%s%c", collect_names, PATH_SEPARATOR);
996 strcat (p, argv[0]);
997 putenv (p);
998
999 prefix_from_env ("COLLECT_NAMES", &our_file_names);
1000
1001 /* Set environment variable COLLECT_NAME to our name so the previous version
1002 of collect won't find us. If it does we'll mutually recurse forever.
1003 This can happen when bootstrapping the new version and an old version is
1004 installed.
1005 ??? Hopefully this bit of code can be removed at some point. */
1006
1007 p = xmalloc (strlen ("COLLECT_NAME=") + strlen (argv[0]) + 1);
1008 sprintf (p, "COLLECT_NAME=%s", argv[0]);
1009 putenv (p);
1010
1011 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
1012 if (p)
1013 while (*p)
1014 {
1015 char *q = p;
1016 while (*q && *q != ' ') q++;
1017 if (*p == '-' && p[1] == 'm')
1018 num_c_args++;
1019
1020 if (*q) q++;
1021 p = q;
1022 }
1023
1024 c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
1025
1026 if (argc < 2)
1027 fatal ("no arguments");
1028
1029#ifdef SIGQUIT
1030 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
1031 signal (SIGQUIT, handler);
1032#endif
1033 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1034 signal (SIGINT, handler);
1035#ifdef SIGALRM
1036 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
1037 signal (SIGALRM, handler);
1038#endif
1039#ifdef SIGHUP
1040 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1041 signal (SIGHUP, handler);
1042#endif
1043 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
1044 signal (SIGSEGV, handler);
1045#ifdef SIGBUS
1046 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
1047 signal (SIGBUS, handler);
1048#endif
1049
1050 /* Extract COMPILER_PATH and PATH into our prefix list. */
1051 prefix_from_env ("COMPILER_PATH", &cpath);
1052 prefix_from_env ("PATH", &path);
1053
1054#ifdef CROSS_COMPILE
1055 /* If we look for a program in the compiler directories, we just use
1056 the short name, since these directories are already system-specific.
973 c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
974
975 if (argc < 2)
976 fatal ("no arguments");
977
978#ifdef SIGQUIT
979 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
980 signal (SIGQUIT, handler);
981#endif
982 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
983 signal (SIGINT, handler);
984#ifdef SIGALRM
985 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
986 signal (SIGALRM, handler);
987#endif
988#ifdef SIGHUP
989 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
990 signal (SIGHUP, handler);
991#endif
992 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
993 signal (SIGSEGV, handler);
994#ifdef SIGBUS
995 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
996 signal (SIGBUS, handler);
997#endif
998
999 /* Extract COMPILER_PATH and PATH into our prefix list. */
1000 prefix_from_env ("COMPILER_PATH", &cpath);
1001 prefix_from_env ("PATH", &path);
1002
1003#ifdef CROSS_COMPILE
1004 /* If we look for a program in the compiler directories, we just use
1005 the short name, since these directories are already system-specific.
1057 But it we look for a took in the system directories, we need to
1006 But it we look for a program in the system directories, we need to
1058 qualify the program name with the target machine. */
1059
1060 full_ld_suffix
1061 = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1);
1062 strcpy (full_ld_suffix, target_machine);
1063 strcat (full_ld_suffix, "-");
1064 strcat (full_ld_suffix, ld_suffix);
1065
1007 qualify the program name with the target machine. */
1008
1009 full_ld_suffix
1010 = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1);
1011 strcpy (full_ld_suffix, target_machine);
1012 strcat (full_ld_suffix, "-");
1013 strcat (full_ld_suffix, ld_suffix);
1014
1066 full_real_ld_suffix
1067 = xcalloc (strlen (real_ld_suffix) + strlen (target_machine) + 2, 1);
1068 strcpy (full_real_ld_suffix, target_machine);
1069 strcat (full_real_ld_suffix, "-");
1070 strcat (full_real_ld_suffix, real_ld_suffix);
1071
1072#if 0
1073 full_gld_suffix
1074 = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);
1075 strcpy (full_gld_suffix, target_machine);
1076 strcat (full_gld_suffix, "-");
1077 strcat (full_gld_suffix, gld_suffix);
1078#endif
1079
1080 full_nm_suffix
1081 = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1);
1082 strcpy (full_nm_suffix, target_machine);
1083 strcat (full_nm_suffix, "-");
1084 strcat (full_nm_suffix, nm_suffix);
1085
1086 full_gnm_suffix
1087 = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1);
1088 strcpy (full_gnm_suffix, target_machine);
1089 strcat (full_gnm_suffix, "-");
1090 strcat (full_gnm_suffix, gnm_suffix);
1091
1092#ifdef LDD_SUFFIX
1093 full_ldd_suffix
1094 = xcalloc (strlen (ldd_suffix) + strlen (target_machine) + 2, 1);
1095 strcpy (full_ldd_suffix, target_machine);
1096 strcat (full_ldd_suffix, "-");
1097 strcat (full_ldd_suffix, ldd_suffix);
1098#endif
1099
1100 full_strip_suffix
1101 = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);
1102 strcpy (full_strip_suffix, target_machine);
1103 strcat (full_strip_suffix, "-");
1104 strcat (full_strip_suffix, strip_suffix);
1105
1106 full_gstrip_suffix
1107 = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1);
1108 strcpy (full_gstrip_suffix, target_machine);
1109 strcat (full_gstrip_suffix, "-");
1110 strcat (full_gstrip_suffix, gstrip_suffix);
1111#endif /* CROSS_COMPILE */
1112
1113 /* Try to discover a valid linker/nm/strip to use. */
1114
1115 /* Maybe we know the right file to use (if not cross). */
1116#ifdef REAL_LD_FILE_NAME
1117 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
1118 if (ld_file_name == 0)
1119#endif
1120 /* Search the (target-specific) compiler dirs for ld'. */
1121 ld_file_name = find_a_file (&cpath, real_ld_suffix);
1122 /* Likewise for `collect-ld'. */
1123 if (ld_file_name == 0)
1124 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
1125 /* Search the compiler directories for `ld'. We have protection against
1126 recursive calls in find_a_file. */
1127 if (ld_file_name == 0)
1128 ld_file_name = find_a_file (&cpath, ld_suffix);
1129 /* Search the ordinary system bin directories
1130 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1131 if (ld_file_name == 0)
1132 ld_file_name = find_a_file (&path, full_ld_suffix);
1133
1015#if 0
1016 full_gld_suffix
1017 = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);
1018 strcpy (full_gld_suffix, target_machine);
1019 strcat (full_gld_suffix, "-");
1020 strcat (full_gld_suffix, gld_suffix);
1021#endif
1022
1023 full_nm_suffix
1024 = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1);
1025 strcpy (full_nm_suffix, target_machine);
1026 strcat (full_nm_suffix, "-");
1027 strcat (full_nm_suffix, nm_suffix);
1028
1029 full_gnm_suffix
1030 = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1);
1031 strcpy (full_gnm_suffix, target_machine);
1032 strcat (full_gnm_suffix, "-");
1033 strcat (full_gnm_suffix, gnm_suffix);
1034
1035#ifdef LDD_SUFFIX
1036 full_ldd_suffix
1037 = xcalloc (strlen (ldd_suffix) + strlen (target_machine) + 2, 1);
1038 strcpy (full_ldd_suffix, target_machine);
1039 strcat (full_ldd_suffix, "-");
1040 strcat (full_ldd_suffix, ldd_suffix);
1041#endif
1042
1043 full_strip_suffix
1044 = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);
1045 strcpy (full_strip_suffix, target_machine);
1046 strcat (full_strip_suffix, "-");
1047 strcat (full_strip_suffix, strip_suffix);
1048
1049 full_gstrip_suffix
1050 = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1);
1051 strcpy (full_gstrip_suffix, target_machine);
1052 strcat (full_gstrip_suffix, "-");
1053 strcat (full_gstrip_suffix, gstrip_suffix);
1054#endif /* CROSS_COMPILE */
1055
1056 /* Try to discover a valid linker/nm/strip to use. */
1057
1058 /* Maybe we know the right file to use (if not cross). */
1059#ifdef REAL_LD_FILE_NAME
1060 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
1061 if (ld_file_name == 0)
1062#endif
1063 /* Search the (target-specific) compiler dirs for ld'. */
1064 ld_file_name = find_a_file (&cpath, real_ld_suffix);
1065 /* Likewise for `collect-ld'. */
1066 if (ld_file_name == 0)
1067 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
1068 /* Search the compiler directories for `ld'. We have protection against
1069 recursive calls in find_a_file. */
1070 if (ld_file_name == 0)
1071 ld_file_name = find_a_file (&cpath, ld_suffix);
1072 /* Search the ordinary system bin directories
1073 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1074 if (ld_file_name == 0)
1075 ld_file_name = find_a_file (&path, full_ld_suffix);
1076
1134 /* If we've invoked ourselves, try again with LD_FILE_NAME. */
1135
1136 if (collect_names != 0)
1137 {
1138 if (ld_file_name != 0)
1139 {
1140 argv[0] = ld_file_name;
1141 execvp (argv[0], argv);
1142 }
1143 fatal ("cannot find `ld'");
1144 }
1145
1146#ifdef REAL_NM_FILE_NAME
1147 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
1148 if (nm_file_name == 0)
1149#endif
1150 nm_file_name = find_a_file (&cpath, gnm_suffix);
1151 if (nm_file_name == 0)
1152 nm_file_name = find_a_file (&path, full_gnm_suffix);
1153 if (nm_file_name == 0)
1154 nm_file_name = find_a_file (&cpath, nm_suffix);
1155 if (nm_file_name == 0)
1156 nm_file_name = find_a_file (&path, full_nm_suffix);
1157
1158#ifdef LDD_SUFFIX
1159 ldd_file_name = find_a_file (&cpath, ldd_suffix);
1160 if (ldd_file_name == 0)
1161 ldd_file_name = find_a_file (&path, full_ldd_suffix);
1162#endif
1163
1164#ifdef REAL_STRIP_FILE_NAME
1165 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1166 if (strip_file_name == 0)
1167#endif
1168 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1169 if (strip_file_name == 0)
1170 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1171 if (strip_file_name == 0)
1172 strip_file_name = find_a_file (&cpath, strip_suffix);
1173 if (strip_file_name == 0)
1174 strip_file_name = find_a_file (&path, full_strip_suffix);
1175
1176 /* Determine the full path name of the C compiler to use. */
1177 c_file_name = getenv ("COLLECT_GCC");
1178 if (c_file_name == 0)
1179 {
1180#ifdef CROSS_COMPILE
1181 c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1);
1182 strcpy (c_file_name, target_machine);
1183 strcat (c_file_name, "-gcc");
1184#else
1185 c_file_name = "gcc";
1186#endif
1187 }
1188
1189 p = find_a_file (&cpath, c_file_name);
1190
1191 /* Here it should be safe to use the system search path since we should have
1192 already qualified the name of the compiler when it is needed. */
1193 if (p == 0)
1194 p = find_a_file (&path, c_file_name);
1195
1196 if (p)
1197 c_file_name = p;
1198
1199 *ld1++ = *ld2++ = ld_file_name;
1200
1077#ifdef REAL_NM_FILE_NAME
1078 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
1079 if (nm_file_name == 0)
1080#endif
1081 nm_file_name = find_a_file (&cpath, gnm_suffix);
1082 if (nm_file_name == 0)
1083 nm_file_name = find_a_file (&path, full_gnm_suffix);
1084 if (nm_file_name == 0)
1085 nm_file_name = find_a_file (&cpath, nm_suffix);
1086 if (nm_file_name == 0)
1087 nm_file_name = find_a_file (&path, full_nm_suffix);
1088
1089#ifdef LDD_SUFFIX
1090 ldd_file_name = find_a_file (&cpath, ldd_suffix);
1091 if (ldd_file_name == 0)
1092 ldd_file_name = find_a_file (&path, full_ldd_suffix);
1093#endif
1094
1095#ifdef REAL_STRIP_FILE_NAME
1096 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1097 if (strip_file_name == 0)
1098#endif
1099 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1100 if (strip_file_name == 0)
1101 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1102 if (strip_file_name == 0)
1103 strip_file_name = find_a_file (&cpath, strip_suffix);
1104 if (strip_file_name == 0)
1105 strip_file_name = find_a_file (&path, full_strip_suffix);
1106
1107 /* Determine the full path name of the C compiler to use. */
1108 c_file_name = getenv ("COLLECT_GCC");
1109 if (c_file_name == 0)
1110 {
1111#ifdef CROSS_COMPILE
1112 c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1);
1113 strcpy (c_file_name, target_machine);
1114 strcat (c_file_name, "-gcc");
1115#else
1116 c_file_name = "gcc";
1117#endif
1118 }
1119
1120 p = find_a_file (&cpath, c_file_name);
1121
1122 /* Here it should be safe to use the system search path since we should have
1123 already qualified the name of the compiler when it is needed. */
1124 if (p == 0)
1125 p = find_a_file (&path, c_file_name);
1126
1127 if (p)
1128 c_file_name = p;
1129
1130 *ld1++ = *ld2++ = ld_file_name;
1131
1201 /* Make temp file names. */
1202 choose_temp_base ();
1203 c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);
1204 o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);
1205 export_file = xmalloc (temp_filename_length + sizeof (".x"));
1206 ldout = xmalloc (temp_filename_length + sizeof (".ld"));
1207 sprintf (ldout, "%s.ld", temp_filename);
1208 sprintf (c_file, "%s.c", temp_filename);
1209 sprintf (o_file, "%s.o", temp_filename);
1210 sprintf (export_file, "%s.x", temp_filename);
1132 /* Make temp file names. */
1133 c_file = make_temp_file (".c");
1134 o_file = make_temp_file (".o");
1135#ifdef COLLECT_EXPORT_LIST
1136 export_file = make_temp_file (".x");
1137 import_file = make_temp_file (".p");
1138#endif
1139 ldout = make_temp_file (".ld");
1211 *c_ptr++ = c_file_name;
1140 *c_ptr++ = c_file_name;
1141 *c_ptr++ = "-x";
1142 *c_ptr++ = "c";
1212 *c_ptr++ = "-c";
1213 *c_ptr++ = "-o";
1214 *c_ptr++ = o_file;
1215
1143 *c_ptr++ = "-c";
1144 *c_ptr++ = "-o";
1145 *c_ptr++ = o_file;
1146
1147#ifdef COLLECT_EXPORT_LIST
1148 /* Generate a list of directories from LIBPATH. */
1149 prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1150 /* Add to this list also two standard directories where
1151 AIX loader always searches for libraries. */
1152 add_prefix (&libpath_lib_dirs, "/lib");
1153 add_prefix (&libpath_lib_dirs, "/usr/lib");
1154#endif
1155
1156 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1157
1158 AIX support needs to know if -shared has been specified before
1159 parsing commandline arguments. */
1160
1161 p = getenv ("COLLECT_GCC_OPTIONS");
1162 while (p && *p)
1163 {
1164 char *q = extract_string (&p);
1165 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1166 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1167 if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0)
1168 shared_obj = 1;
1169 }
1170 obstack_free (&temporary_obstack, temporary_firstobj);
1171 *c_ptr++ = "-fno-exceptions";
1172
1216 /* !!! When GCC calls collect2,
1217 it does not know whether it is calling collect2 or ld.
1218 So collect2 cannot meaningfully understand any options
1219 except those ld understands.
1220 If you propose to make GCC pass some other option,
1221 just imagine what will happen if ld is really ld!!! */
1222
1173 /* !!! When GCC calls collect2,
1174 it does not know whether it is calling collect2 or ld.
1175 So collect2 cannot meaningfully understand any options
1176 except those ld understands.
1177 If you propose to make GCC pass some other option,
1178 just imagine what will happen if ld is really ld!!! */
1179
1223 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1180 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1224 /* After the first file, put in the c++ rt0. */
1225
1226 first_file = 1;
1181 /* After the first file, put in the c++ rt0. */
1182
1183 first_file = 1;
1227 while ((arg = *++argv) != (char *)0)
1184 while ((arg = *++argv) != (char *) 0)
1228 {
1229 *ld1++ = *ld2++ = arg;
1230
1231 if (arg[0] == '-')
1232 {
1233 switch (arg[1])
1234 {
1185 {
1186 *ld1++ = *ld2++ = arg;
1187
1188 if (arg[0] == '-')
1189 {
1190 switch (arg[1])
1191 {
1192#ifdef COLLECT_EXPORT_LIST
1193 /* We want to disable automatic exports on AIX when user
1194 explicitly puts an export list in command line */
1195 case 'b':
1196 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1197 export_flag = 1;
1198 if (arg[2] == '6' && arg[3] == '4')
1199 aix64_flag = 1;
1200 break;
1201#endif
1202
1235 case 'd':
1236 if (!strcmp (arg, "-debug"))
1237 {
1203 case 'd':
1204 if (!strcmp (arg, "-debug"))
1205 {
1238 debug = 1;
1239 vflag = 1;
1206 /* Already parsed. */
1240 ld1--;
1241 ld2--;
1242 }
1243 break;
1244
1245 case 'l':
1246 if (first_file)
1247 {
1248 /* place o_file BEFORE this argument! */
1249 first_file = 0;
1250 ld2--;
1251 *ld2++ = o_file;
1252 *ld2++ = arg;
1253 }
1207 ld1--;
1208 ld2--;
1209 }
1210 break;
1211
1212 case 'l':
1213 if (first_file)
1214 {
1215 /* place o_file BEFORE this argument! */
1216 first_file = 0;
1217 ld2--;
1218 *ld2++ = o_file;
1219 *ld2++ = arg;
1220 }
1221#ifdef COLLECT_EXPORT_LIST
1222 {
1223 /* Resolving full library name. */
1224 char *s = resolve_lib_name (arg+2);
1225
1226 /* If we will use an import list for this library,
1227 we should exclude it from ld args. */
1228 if (use_import_list (s))
1229 {
1230 ld1--;
1231 ld2--;
1232 }
1233
1234 /* Saving a full library name. */
1235 add_to_list (&libs, s);
1236 }
1237#endif
1254 break;
1255
1238 break;
1239
1240#ifdef COLLECT_EXPORT_LIST
1241 /* Saving directories where to search for libraries. */
1242 case 'L':
1243 add_prefix (&cmdline_lib_dirs, arg+2);
1244 break;
1245#endif
1246
1256 case 'o':
1257 if (arg[2] == '\0')
1258 output_file = *ld1++ = *ld2++ = *++argv;
1259 else
1260 output_file = &arg[2];
1261 break;
1262
1263 case 'r':
1264 if (arg[2] == '\0')
1265 rflag = 1;
1266 break;
1267
1268 case 's':
1269 if (arg[2] == '\0' && do_collecting)
1270 {
1271 /* We must strip after the nm run, otherwise C++ linking
1247 case 'o':
1248 if (arg[2] == '\0')
1249 output_file = *ld1++ = *ld2++ = *++argv;
1250 else
1251 output_file = &arg[2];
1252 break;
1253
1254 case 'r':
1255 if (arg[2] == '\0')
1256 rflag = 1;
1257 break;
1258
1259 case 's':
1260 if (arg[2] == '\0' && do_collecting)
1261 {
1262 /* We must strip after the nm run, otherwise C++ linking
1272 won't work. Thus we strip in the second ld run, or
1263 will not work. Thus we strip in the second ld run, or
1273 else with strip if there is no second ld run. */
1274 strip_flag = 1;
1275 ld1--;
1276 }
1277 break;
1278
1279 case 'v':
1280 if (arg[2] == '\0')
1281 vflag = 1;
1282 break;
1283 }
1284 }
1264 else with strip if there is no second ld run. */
1265 strip_flag = 1;
1266 ld1--;
1267 }
1268 break;
1269
1270 case 'v':
1271 if (arg[2] == '\0')
1272 vflag = 1;
1273 break;
1274 }
1275 }
1285 else if ((p = rindex (arg, '.')) != (char *)0
1286 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0))
1276 else if ((p = rindex (arg, '.')) != (char *) 0
1277 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1278 || strcmp (p, ".so") == 0))
1287 {
1288 if (first_file)
1289 {
1290 first_file = 0;
1291 if (p[1] == 'o')
1292 *ld2++ = o_file;
1293 else
1294 {
1295 /* place o_file BEFORE this argument! */
1296 ld2--;
1297 *ld2++ = o_file;
1298 *ld2++ = arg;
1299 }
1300 }
1301 if (p[1] == 'o')
1302 *object++ = arg;
1279 {
1280 if (first_file)
1281 {
1282 first_file = 0;
1283 if (p[1] == 'o')
1284 *ld2++ = o_file;
1285 else
1286 {
1287 /* place o_file BEFORE this argument! */
1288 ld2--;
1289 *ld2++ = o_file;
1290 *ld2++ = arg;
1291 }
1292 }
1293 if (p[1] == 'o')
1294 *object++ = arg;
1295#ifdef COLLECT_EXPORT_LIST
1296 /* libraries can be specified directly, i.e. without -l flag. */
1297 else
1298 {
1299 /* If we will use an import list for this library,
1300 we should exclude it from ld args. */
1301 if (use_import_list (arg))
1302 {
1303 ld1--;
1304 ld2--;
1305 }
1306
1307 /* Saving a full library name. */
1308 add_to_list (&libs, arg);
1309 }
1310#endif
1303 }
1304 }
1305
1311 }
1312 }
1313
1306 /* Get any options that the upper GCC wants to pass to the sub-GCC. */
1307 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
1308 if (p)
1309 while (*p)
1310 {
1311 char *q = p;
1312 while (*q && *q != ' ') q++;
1313 if (*p == '-' && (p[1] == 'm' || p[1] == 'f'))
1314 *c_ptr++ = savestring (p, q - p);
1315 if (strncmp (p, "-shared", sizeof ("shared") - 1) == 0)
1316 shared_obj = 1;
1317
1318 if (*q) q++;
1319 p = q;
1320 }
1321
1322#ifdef COLLECT_EXPORT_LIST
1314#ifdef COLLECT_EXPORT_LIST
1315 /* This is added only for debugging purposes. */
1316 if (debug)
1317 {
1318 fprintf (stderr, "List of libraries:\n");
1319 dump_list (stderr, "\t", libs.first);
1320 }
1321
1323 /* The AIX linker will discard static constructors in object files if
1324 nothing else in the file is referenced, so look at them first. */
1322 /* The AIX linker will discard static constructors in object files if
1323 nothing else in the file is referenced, so look at them first. */
1325 while (object_lst < object)
1326 scan_prog_file (*object_lst++, PASS_OBJ);
1327
1328 {
1324 {
1329 char *buf = alloca (strlen (export_file) + 5);
1330 sprintf (buf, "-bE:%s", export_file);
1331 *ld1++ = buf;
1332 *ld2++ = buf;
1325 char **export_object_lst = object_lst;
1326 while (export_object_lst < object)
1327 scan_prog_file (*export_object_lst++, PASS_OBJ);
1328 }
1329 {
1330 struct id *list = libs.first;
1331 for (; list; list = list->next)
1332 scan_prog_file (list->name, PASS_FIRST);
1333 }
1334 {
1335 char *buf1 = alloca (strlen (export_file) + 5);
1336 char *buf2 = alloca (strlen (import_file) + 5);
1337 sprintf (buf1, "-bE:%s", export_file);
1338 sprintf (buf2, "-bI:%s", import_file);
1339 *ld1++ = buf1;
1340 *ld2++ = buf1;
1341 *ld1++ = buf2;
1342 *ld2++ = buf2;
1333 exportf = fopen (export_file, "w");
1343 exportf = fopen (export_file, "w");
1334 if (exportf == (FILE *)0)
1344 if (exportf == (FILE *) 0)
1335 fatal_perror ("%s", export_file);
1336 write_export_file (exportf);
1337 if (fclose (exportf))
1338 fatal_perror ("closing %s", export_file);
1345 fatal_perror ("%s", export_file);
1346 write_export_file (exportf);
1347 if (fclose (exportf))
1348 fatal_perror ("closing %s", export_file);
1349 importf = fopen (import_file, "w");
1350 if (importf == (FILE *) 0)
1351 fatal_perror ("%s", import_file);
1352 write_import_file (importf);
1353 if (fclose (importf))
1354 fatal_perror ("closing %s", import_file);
1339 }
1340#endif
1341
1342 *c_ptr++ = c_file;
1355 }
1356#endif
1357
1358 *c_ptr++ = c_file;
1343 *object = *c_ptr = *ld1 = (char *)0;
1359 *object = *c_ptr = *ld1 = (char *) 0;
1344
1345 if (vflag)
1346 {
1347 fprintf (stderr, "collect2 version %s", version_string);
1348#ifdef TARGET_VERSION
1349 TARGET_VERSION;
1350#endif
1351 fprintf (stderr, "\n");
1352 }
1353
1354 if (debug)
1355 {
1356 char *ptr;
1357 fprintf (stderr, "ld_file_name = %s\n",
1358 (ld_file_name ? ld_file_name : "not found"));
1359 fprintf (stderr, "c_file_name = %s\n",
1360 (c_file_name ? c_file_name : "not found"));
1361 fprintf (stderr, "nm_file_name = %s\n",
1362 (nm_file_name ? nm_file_name : "not found"));
1363#ifdef LDD_SUFFIX
1364 fprintf (stderr, "ldd_file_name = %s\n",
1365 (ldd_file_name ? ldd_file_name : "not found"));
1366#endif
1367 fprintf (stderr, "strip_file_name = %s\n",
1368 (strip_file_name ? strip_file_name : "not found"));
1369 fprintf (stderr, "c_file = %s\n",
1370 (c_file ? c_file : "not found"));
1371 fprintf (stderr, "o_file = %s\n",
1372 (o_file ? o_file : "not found"));
1373
1360
1361 if (vflag)
1362 {
1363 fprintf (stderr, "collect2 version %s", version_string);
1364#ifdef TARGET_VERSION
1365 TARGET_VERSION;
1366#endif
1367 fprintf (stderr, "\n");
1368 }
1369
1370 if (debug)
1371 {
1372 char *ptr;
1373 fprintf (stderr, "ld_file_name = %s\n",
1374 (ld_file_name ? ld_file_name : "not found"));
1375 fprintf (stderr, "c_file_name = %s\n",
1376 (c_file_name ? c_file_name : "not found"));
1377 fprintf (stderr, "nm_file_name = %s\n",
1378 (nm_file_name ? nm_file_name : "not found"));
1379#ifdef LDD_SUFFIX
1380 fprintf (stderr, "ldd_file_name = %s\n",
1381 (ldd_file_name ? ldd_file_name : "not found"));
1382#endif
1383 fprintf (stderr, "strip_file_name = %s\n",
1384 (strip_file_name ? strip_file_name : "not found"));
1385 fprintf (stderr, "c_file = %s\n",
1386 (c_file ? c_file : "not found"));
1387 fprintf (stderr, "o_file = %s\n",
1388 (o_file ? o_file : "not found"));
1389
1374 ptr = getenv ("COLLECT_NAMES");
1375 if (ptr)
1376 fprintf (stderr, "COLLECT_NAMES = %s\n", ptr);
1377
1378 ptr = getenv ("COLLECT_GCC_OPTIONS");
1379 if (ptr)
1380 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1381
1382 ptr = getenv ("COLLECT_GCC");
1383 if (ptr)
1384 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1385
1386 ptr = getenv ("COMPILER_PATH");
1387 if (ptr)
1388 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1389
1390 ptr = getenv ("LIBRARY_PATH");
1391 if (ptr)
1392 fprintf (stderr, "LIBRARY_PATH = %s\n", ptr);
1393
1394 fprintf (stderr, "\n");
1395 }
1396
1390 ptr = getenv ("COLLECT_GCC_OPTIONS");
1391 if (ptr)
1392 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1393
1394 ptr = getenv ("COLLECT_GCC");
1395 if (ptr)
1396 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1397
1398 ptr = getenv ("COMPILER_PATH");
1399 if (ptr)
1400 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1401
1402 ptr = getenv ("LIBRARY_PATH");
1403 if (ptr)
1404 fprintf (stderr, "LIBRARY_PATH = %s\n", ptr);
1405
1406 fprintf (stderr, "\n");
1407 }
1408
1397 /* Load the program, searching all libraries. */
1409 /* Load the program, searching all libraries and attempting to provide
1410 undefined symbols from repository information. */
1398
1411
1399 collect_execute ("ld", ld1_argv, ldout);
1400 do_wait ("ld");
1401 dump_file (ldout);
1402 unlink (ldout);
1412 /* On AIX we do this later. */
1413#ifndef COLLECT_EXPORT_LIST
1414 do_tlink (ld1_argv, object_lst);
1415#endif
1403
1416
1404 /* If -r or they'll be run via some other method, don't build the
1405 constructor or destructor list, just return now. */
1406 if (rflag || ! do_collecting)
1407 return 0;
1417 /* If -r or they will be run via some other method, do not build the
1418 constructor or destructor list, just return now. */
1419 if (rflag
1420#ifndef COLLECT_EXPORT_LIST
1421 || ! do_collecting
1422#endif
1423 )
1424 {
1425#ifdef COLLECT_EXPORT_LIST
1426 /* But make sure we delete the export file we may have created. */
1427 if (export_file != 0 && export_file[0])
1428 maybe_unlink (export_file);
1429 if (import_file != 0 && import_file[0])
1430 maybe_unlink (import_file);
1431#endif
1432 maybe_unlink (c_file);
1433 maybe_unlink (o_file);
1434 return 0;
1435 }
1408
1409 /* Examine the namelist with nm and search it for static constructors
1410 and destructors to call.
1436
1437 /* Examine the namelist with nm and search it for static constructors
1438 and destructors to call.
1411 Write the constructor and destructor tables to a .s file and reload. */
1439 Write the constructor and destructor tables to a .s file and reload. */
1412
1440
1441 /* On AIX we already done scanning for global constructors/destructors. */
1442#ifndef COLLECT_EXPORT_LIST
1413 scan_prog_file (output_file, PASS_FIRST);
1443 scan_prog_file (output_file, PASS_FIRST);
1444#endif
1414
1415#ifdef SCAN_LIBRARIES
1416 scan_libraries (output_file);
1417#endif
1418
1419 if (debug)
1420 {
1421 fprintf (stderr, "%d constructor(s) found\n", constructors.number);
1422 fprintf (stderr, "%d destructor(s) found\n", destructors.number);
1423 }
1424
1425 if (constructors.number == 0 && destructors.number == 0
1445
1446#ifdef SCAN_LIBRARIES
1447 scan_libraries (output_file);
1448#endif
1449
1450 if (debug)
1451 {
1452 fprintf (stderr, "%d constructor(s) found\n", constructors.number);
1453 fprintf (stderr, "%d destructor(s) found\n", destructors.number);
1454 }
1455
1456 if (constructors.number == 0 && destructors.number == 0
1426#ifdef LDD_SUFFIX
1457 && frame_tables.number == 0
1458#if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1427 /* If we will be running these functions ourselves, we want to emit
1459 /* If we will be running these functions ourselves, we want to emit
1428 stubs into the shared library so that we don't have to relink
1460 stubs into the shared library so that we do not have to relink
1429 dependent programs when we add static objects. */
1430 && ! shared_obj
1431#endif
1432 )
1433 {
1461 dependent programs when we add static objects. */
1462 && ! shared_obj
1463#endif
1464 )
1465 {
1466#ifdef COLLECT_EXPORT_LIST
1467 /* Doing tlink without additional code generation */
1468 do_tlink (ld1_argv, object_lst);
1469#endif
1434 /* Strip now if it was requested on the command line. */
1435 if (strip_flag)
1436 {
1437 char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
1438 strip_argv[0] = strip_file_name;
1439 strip_argv[1] = output_file;
1440 strip_argv[2] = (char *) 0;
1441 fork_execute ("strip", strip_argv);
1442 }
1443
1444#ifdef COLLECT_EXPORT_LIST
1445 maybe_unlink (export_file);
1470 /* Strip now if it was requested on the command line. */
1471 if (strip_flag)
1472 {
1473 char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
1474 strip_argv[0] = strip_file_name;
1475 strip_argv[1] = output_file;
1476 strip_argv[2] = (char *) 0;
1477 fork_execute ("strip", strip_argv);
1478 }
1479
1480#ifdef COLLECT_EXPORT_LIST
1481 maybe_unlink (export_file);
1482 maybe_unlink (import_file);
1446#endif
1483#endif
1484 maybe_unlink (c_file);
1485 maybe_unlink (o_file);
1447 return 0;
1448 }
1449
1450 maybe_unlink(output_file);
1451 outf = fopen (c_file, "w");
1486 return 0;
1487 }
1488
1489 maybe_unlink(output_file);
1490 outf = fopen (c_file, "w");
1452 if (outf == (FILE *)0)
1491 if (outf == (FILE *) 0)
1453 fatal_perror ("%s", c_file);
1454
1455 write_c_file (outf, c_file);
1456
1457 if (fclose (outf))
1458 fatal_perror ("closing %s", c_file);
1459
1460 /* Tell the linker that we have initializer and finalizer functions. */
1461#ifdef LD_INIT_SWITCH
1462 *ld2++ = LD_INIT_SWITCH;
1463 *ld2++ = initname;
1464 *ld2++ = LD_FINI_SWITCH;
1465 *ld2++ = fininame;
1466#endif
1492 fatal_perror ("%s", c_file);
1493
1494 write_c_file (outf, c_file);
1495
1496 if (fclose (outf))
1497 fatal_perror ("closing %s", c_file);
1498
1499 /* Tell the linker that we have initializer and finalizer functions. */
1500#ifdef LD_INIT_SWITCH
1501 *ld2++ = LD_INIT_SWITCH;
1502 *ld2++ = initname;
1503 *ld2++ = LD_FINI_SWITCH;
1504 *ld2++ = fininame;
1505#endif
1467 *ld2 = (char*)0;
1506 *ld2 = (char*) 0;
1468
1469#ifdef COLLECT_EXPORT_LIST
1470 if (shared_obj)
1471 {
1472 add_to_list (&exports, initname);
1473 add_to_list (&exports, fininame);
1474 add_to_list (&exports, "_GLOBAL__DI");
1475 add_to_list (&exports, "_GLOBAL__DD");
1476 exportf = fopen (export_file, "w");
1507
1508#ifdef COLLECT_EXPORT_LIST
1509 if (shared_obj)
1510 {
1511 add_to_list (&exports, initname);
1512 add_to_list (&exports, fininame);
1513 add_to_list (&exports, "_GLOBAL__DI");
1514 add_to_list (&exports, "_GLOBAL__DD");
1515 exportf = fopen (export_file, "w");
1477 if (exportf == (FILE *)0)
1516 if (exportf == (FILE *) 0)
1478 fatal_perror ("%s", export_file);
1479 write_export_file (exportf);
1480 if (fclose (exportf))
1481 fatal_perror ("closing %s", export_file);
1482 }
1483#endif
1484
1485 if (debug)
1486 {
1487 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1488 output_file, c_file);
1489 write_c_file (stderr, "stderr");
1490 fprintf (stderr, "========== end of c_file\n\n");
1491#ifdef COLLECT_EXPORT_LIST
1492 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1493 write_export_file (stderr);
1494 fprintf (stderr, "========== end of export_file\n\n");
1495#endif
1496 }
1497
1498 /* Assemble the constructor and destructor tables.
1517 fatal_perror ("%s", export_file);
1518 write_export_file (exportf);
1519 if (fclose (exportf))
1520 fatal_perror ("closing %s", export_file);
1521 }
1522#endif
1523
1524 if (debug)
1525 {
1526 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1527 output_file, c_file);
1528 write_c_file (stderr, "stderr");
1529 fprintf (stderr, "========== end of c_file\n\n");
1530#ifdef COLLECT_EXPORT_LIST
1531 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1532 write_export_file (stderr);
1533 fprintf (stderr, "========== end of export_file\n\n");
1534#endif
1535 }
1536
1537 /* Assemble the constructor and destructor tables.
1499 Link the tables in with the rest of the program. */
1538 Link the tables in with the rest of the program. */
1500
1501 fork_execute ("gcc", c_argv);
1539
1540 fork_execute ("gcc", c_argv);
1541#ifdef COLLECT_EXPORT_LIST
1542 /* On AIX we must call tlink because of possible templates resolution */
1543 do_tlink (ld2_argv, object_lst);
1544#else
1545 /* Otherwise, simply call ld because tlink is already done */
1502 fork_execute ("ld", ld2_argv);
1503
1504 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1505 constructors/destructors in shared libraries. */
1506 scan_prog_file (output_file, PASS_SECOND);
1546 fork_execute ("ld", ld2_argv);
1547
1548 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1549 constructors/destructors in shared libraries. */
1550 scan_prog_file (output_file, PASS_SECOND);
1551#endif
1507
1508 maybe_unlink (c_file);
1509 maybe_unlink (o_file);
1552
1553 maybe_unlink (c_file);
1554 maybe_unlink (o_file);
1555
1556#ifdef COLLECT_EXPORT_LIST
1510 maybe_unlink (export_file);
1557 maybe_unlink (export_file);
1558 maybe_unlink (import_file);
1559#endif
1560
1511 return 0;
1512}
1513
1514
1561 return 0;
1562}
1563
1564
1515/* Wait for a process to finish, and exit if a non-zero status is found. */
1565/* Wait for a process to finish, and exit if a non-zero status is found. */
1516
1517int
1518collect_wait (prog)
1519 char *prog;
1520{
1521 int status;
1522
1523 wait (&status);
1524 if (status)
1525 {
1526 if (WIFSIGNALED (status))
1527 {
1528 int sig = WTERMSIG (status);
1529#ifdef NO_SYS_SIGLIST
1530 error ("%s terminated with signal %d %s",
1531 prog,
1532 sig,
1533 (status & 0200) ? ", core dumped" : "");
1534#else
1535 error ("%s terminated with signal %d [%s]%s",
1536 prog,
1537 sig,
1538 sys_siglist[sig],
1539 (status & 0200) ? ", core dumped" : "");
1540#endif
1541
1566
1567int
1568collect_wait (prog)
1569 char *prog;
1570{
1571 int status;
1572
1573 wait (&status);
1574 if (status)
1575 {
1576 if (WIFSIGNALED (status))
1577 {
1578 int sig = WTERMSIG (status);
1579#ifdef NO_SYS_SIGLIST
1580 error ("%s terminated with signal %d %s",
1581 prog,
1582 sig,
1583 (status & 0200) ? ", core dumped" : "");
1584#else
1585 error ("%s terminated with signal %d [%s]%s",
1586 prog,
1587 sig,
1588 sys_siglist[sig],
1589 (status & 0200) ? ", core dumped" : "");
1590#endif
1591
1542 collect_exit (127);
1592 collect_exit (FATAL_EXIT_CODE);
1543 }
1544
1545 if (WIFEXITED (status))
1546 return WEXITSTATUS (status);
1547 }
1548 return 0;
1549}
1550
1551static void
1552do_wait (prog)
1553 char *prog;
1554{
1555 int ret = collect_wait (prog);
1556 if (ret != 0)
1557 {
1558 error ("%s returned %d exit status", prog, ret);
1559 collect_exit (ret);
1560 }
1561}
1562
1563
1564/* Fork and execute a program, and wait for the reply. */
1565
1566void
1567collect_execute (prog, argv, redir)
1568 char *prog;
1569 char **argv;
1570 char *redir;
1571{
1572 int pid;
1573
1574 if (vflag || debug)
1575 {
1576 char **p_argv;
1577 char *str;
1578
1579 if (argv[0])
1580 fprintf (stderr, "%s", argv[0]);
1581 else
1582 fprintf (stderr, "[cannot find %s]", prog);
1583
1593 }
1594
1595 if (WIFEXITED (status))
1596 return WEXITSTATUS (status);
1597 }
1598 return 0;
1599}
1600
1601static void
1602do_wait (prog)
1603 char *prog;
1604{
1605 int ret = collect_wait (prog);
1606 if (ret != 0)
1607 {
1608 error ("%s returned %d exit status", prog, ret);
1609 collect_exit (ret);
1610 }
1611}
1612
1613
1614/* Fork and execute a program, and wait for the reply. */
1615
1616void
1617collect_execute (prog, argv, redir)
1618 char *prog;
1619 char **argv;
1620 char *redir;
1621{
1622 int pid;
1623
1624 if (vflag || debug)
1625 {
1626 char **p_argv;
1627 char *str;
1628
1629 if (argv[0])
1630 fprintf (stderr, "%s", argv[0]);
1631 else
1632 fprintf (stderr, "[cannot find %s]", prog);
1633
1584 for (p_argv = &argv[1]; (str = *p_argv) != (char *)0; p_argv++)
1634 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1585 fprintf (stderr, " %s", str);
1586
1587 fprintf (stderr, "\n");
1588 }
1589
1590 fflush (stdout);
1591 fflush (stderr);
1592
1635 fprintf (stderr, " %s", str);
1636
1637 fprintf (stderr, "\n");
1638 }
1639
1640 fflush (stdout);
1641 fflush (stderr);
1642
1593 /* If we can't find a program we need, complain error. Do this here
1594 since we might not end up needing something that we couldn't find. */
1643 /* If we cannot find a program we need, complain error. Do this here
1644 since we might not end up needing something that we could not find. */
1595
1596 if (argv[0] == 0)
1597 fatal ("cannot find `%s'", prog);
1598
1645
1646 if (argv[0] == 0)
1647 fatal ("cannot find `%s'", prog);
1648
1649#ifndef __CYGWIN32__
1599 pid = vfork ();
1600 if (pid == -1)
1601 {
1602#ifdef vfork
1603 fatal_perror ("fork");
1604#else
1605 fatal_perror ("vfork");
1606#endif
1607 }
1608
1609 if (pid == 0) /* child context */
1610 {
1611 if (redir)
1612 {
1613 unlink (redir);
1614 if (freopen (redir, "a", stdout) == NULL)
1650 pid = vfork ();
1651 if (pid == -1)
1652 {
1653#ifdef vfork
1654 fatal_perror ("fork");
1655#else
1656 fatal_perror ("vfork");
1657#endif
1658 }
1659
1660 if (pid == 0) /* child context */
1661 {
1662 if (redir)
1663 {
1664 unlink (redir);
1665 if (freopen (redir, "a", stdout) == NULL)
1615 fatal_perror ("redirecting stdout");
1666 fatal_perror ("redirecting stdout: %s", redir);
1616 if (freopen (redir, "a", stderr) == NULL)
1667 if (freopen (redir, "a", stderr) == NULL)
1617 fatal_perror ("redirecting stderr");
1668 fatal_perror ("redirecting stderr: %s", redir);
1618 }
1619
1620 execvp (argv[0], argv);
1621 fatal_perror ("executing %s", prog);
1622 }
1669 }
1670
1671 execvp (argv[0], argv);
1672 fatal_perror ("executing %s", prog);
1673 }
1674#else
1675 pid = _spawnvp (_P_NOWAIT, argv[0], argv);
1676 if (pid == -1)
1677 fatal ("spawnvp failed");
1678#endif
1623}
1624
1625static void
1626fork_execute (prog, argv)
1627 char *prog;
1628 char **argv;
1629{
1630 collect_execute (prog, argv, NULL);
1631 do_wait (prog);
1632}
1633
1634/* Unlink a file unless we are debugging. */
1635
1636static void
1637maybe_unlink (file)
1638 char *file;
1639{
1640 if (!debug)
1641 unlink (file);
1642 else
1643 fprintf (stderr, "[Leaving %s]\n", file);
1644}
1645
1646
1647/* Add a name to a linked list. */
1648
1649static void
1650add_to_list (head_ptr, name)
1651 struct head *head_ptr;
1652 char *name;
1653{
1654 struct id *newid
1655 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1656 struct id *p;
1657 static long sequence_number = 0;
1658 strcpy (newid->name, name);
1659
1660 if (head_ptr->first)
1661 head_ptr->last->next = newid;
1662 else
1663 head_ptr->first = newid;
1664
1665 /* Check for duplicate symbols. */
1666 for (p = head_ptr->first;
1667 strcmp (name, p->name) != 0;
1668 p = p->next)
1669 ;
1670 if (p != newid)
1671 {
1672 head_ptr->last->next = 0;
1673 free (newid);
1674 return;
1675 }
1676
1677 newid->sequence = ++sequence_number;
1678 head_ptr->last = newid;
1679 head_ptr->number++;
1680}
1681
1682/* Write: `prefix', the names on list LIST, `suffix'. */
1683
1684static void
1685write_list (stream, prefix, list)
1686 FILE *stream;
1687 char *prefix;
1688 struct id *list;
1689{
1690 while (list)
1691 {
1692 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1693 list = list->next;
1694 }
1695}
1696
1679}
1680
1681static void
1682fork_execute (prog, argv)
1683 char *prog;
1684 char **argv;
1685{
1686 collect_execute (prog, argv, NULL);
1687 do_wait (prog);
1688}
1689
1690/* Unlink a file unless we are debugging. */
1691
1692static void
1693maybe_unlink (file)
1694 char *file;
1695{
1696 if (!debug)
1697 unlink (file);
1698 else
1699 fprintf (stderr, "[Leaving %s]\n", file);
1700}
1701
1702
1703/* Add a name to a linked list. */
1704
1705static void
1706add_to_list (head_ptr, name)
1707 struct head *head_ptr;
1708 char *name;
1709{
1710 struct id *newid
1711 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1712 struct id *p;
1713 static long sequence_number = 0;
1714 strcpy (newid->name, name);
1715
1716 if (head_ptr->first)
1717 head_ptr->last->next = newid;
1718 else
1719 head_ptr->first = newid;
1720
1721 /* Check for duplicate symbols. */
1722 for (p = head_ptr->first;
1723 strcmp (name, p->name) != 0;
1724 p = p->next)
1725 ;
1726 if (p != newid)
1727 {
1728 head_ptr->last->next = 0;
1729 free (newid);
1730 return;
1731 }
1732
1733 newid->sequence = ++sequence_number;
1734 head_ptr->last = newid;
1735 head_ptr->number++;
1736}
1737
1738/* Write: `prefix', the names on list LIST, `suffix'. */
1739
1740static void
1741write_list (stream, prefix, list)
1742 FILE *stream;
1743 char *prefix;
1744 struct id *list;
1745{
1746 while (list)
1747 {
1748 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1749 list = list->next;
1750 }
1751}
1752
1753#ifdef COLLECT_EXPORT_LIST
1754/* This function is really used only on AIX, but may be useful. */
1755static int
1756is_in_list (prefix, list)
1757 char *prefix;
1758 struct id *list;
1759{
1760 while (list)
1761 {
1762 if (!strcmp (prefix, list->name)) return 1;
1763 list = list->next;
1764 }
1765 return 0;
1766}
1767#endif
1768
1769/* Added for debugging purpose. */
1770#ifdef COLLECT_EXPORT_LIST
1697static void
1771static void
1772dump_list (stream, prefix, list)
1773 FILE *stream;
1774 char *prefix;
1775 struct id *list;
1776{
1777 while (list)
1778 {
1779 fprintf (stream, "%s%s,\n", prefix, list->name);
1780 list = list->next;
1781 }
1782}
1783#endif
1784
1785#if 0
1786static void
1787dump_prefix_list (stream, prefix, list)
1788 FILE *stream;
1789 char *prefix;
1790 struct prefix_list *list;
1791{
1792 while (list)
1793 {
1794 fprintf (stream, "%s%s,\n", prefix, list->prefix);
1795 list = list->next;
1796 }
1797}
1798#endif
1799
1800static void
1698write_list_with_asm (stream, prefix, list)
1699 FILE *stream;
1700 char *prefix;
1701 struct id *list;
1702{
1703 while (list)
1704 {
1705 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1706 prefix, list->sequence, list->name);
1707 list = list->next;
1708 }
1709}
1710
1711/* Write out the constructor and destructor tables statically (for a shared
1712 object), along with the functions to execute them. */
1713
1714static void
1715write_c_file_stat (stream, name)
1716 FILE *stream;
1717 char *name;
1718{
1719 char *prefix, *p, *q;
1801write_list_with_asm (stream, prefix, list)
1802 FILE *stream;
1803 char *prefix;
1804 struct id *list;
1805{
1806 while (list)
1807 {
1808 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1809 prefix, list->sequence, list->name);
1810 list = list->next;
1811 }
1812}
1813
1814/* Write out the constructor and destructor tables statically (for a shared
1815 object), along with the functions to execute them. */
1816
1817static void
1818write_c_file_stat (stream, name)
1819 FILE *stream;
1820 char *name;
1821{
1822 char *prefix, *p, *q;
1823 int frames = (frame_tables.number > 0);
1720
1721 /* Figure out name of output_file, stripping off .so version. */
1722 p = rindex (output_file, '/');
1723 if (p == 0)
1724 p = (char *) output_file;
1725 else
1726 p++;
1727 q = p;
1728 while (q)
1729 {
1730 q = index (q,'.');
1731 if (q == 0)
1732 {
1733 q = p + strlen (p);
1734 break;
1735 }
1736 else
1737 {
1738 if (strncmp (q, ".so", 3) == 0)
1739 {
1740 q += 3;
1741 break;
1742 }
1743 else
1744 q++;
1745 }
1746 }
1747 /* q points to null at end of the string (or . of the .so version) */
1748 prefix = xmalloc (q - p + 1);
1749 strncpy (prefix, p, q - p);
1750 prefix[q - p] = 0;
1751 for (q = prefix; *q; q++)
1824
1825 /* Figure out name of output_file, stripping off .so version. */
1826 p = rindex (output_file, '/');
1827 if (p == 0)
1828 p = (char *) output_file;
1829 else
1830 p++;
1831 q = p;
1832 while (q)
1833 {
1834 q = index (q,'.');
1835 if (q == 0)
1836 {
1837 q = p + strlen (p);
1838 break;
1839 }
1840 else
1841 {
1842 if (strncmp (q, ".so", 3) == 0)
1843 {
1844 q += 3;
1845 break;
1846 }
1847 else
1848 q++;
1849 }
1850 }
1851 /* q points to null at end of the string (or . of the .so version) */
1852 prefix = xmalloc (q - p + 1);
1853 strncpy (prefix, p, q - p);
1854 prefix[q - p] = 0;
1855 for (q = prefix; *q; q++)
1752 if (!isalnum (*q))
1856 if (!ISALNUM (*q))
1753 *q = '_';
1754 if (debug)
1755 fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n",
1756 output_file, prefix);
1757
1758#define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1759 initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
1760 sprintf (initname, INIT_NAME_FORMAT, prefix);
1761
1762#define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1763 fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
1764 sprintf (fininame, FINI_NAME_FORMAT, prefix);
1765
1766 free (prefix);
1767
1768 /* Write the tables as C code */
1769
1770 fprintf (stream, "static int count;\n");
1771 fprintf (stream, "typedef void entry_pt();\n");
1772 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1857 *q = '_';
1858 if (debug)
1859 fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n",
1860 output_file, prefix);
1861
1862#define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1863 initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
1864 sprintf (initname, INIT_NAME_FORMAT, prefix);
1865
1866#define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1867 fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
1868 sprintf (fininame, FINI_NAME_FORMAT, prefix);
1869
1870 free (prefix);
1871
1872 /* Write the tables as C code */
1873
1874 fprintf (stream, "static int count;\n");
1875 fprintf (stream, "typedef void entry_pt();\n");
1876 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1877
1878 if (frames)
1879 {
1880 write_list_with_asm (stream, "extern void *", frame_tables.first);
1881
1882 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1883 write_list (stream, "\t\t&", frame_tables.first);
1884 fprintf (stream, "\t0\n};\n");
1885
1886 /* This must match what's in frame.h. */
1887 fprintf (stream, "struct object {\n");
1888 fprintf (stream, " void *pc_begin;\n");
1889 fprintf (stream, " void *pc_end;\n");
1890 fprintf (stream, " void *fde_begin;\n");
1891 fprintf (stream, " void *fde_array;\n");
1892 fprintf (stream, " __SIZE_TYPE__ count;\n");
1893 fprintf (stream, " struct object *next;\n");
1894 fprintf (stream, "};\n");
1895
1896 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1897 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1898
1899 fprintf (stream, "static void reg_frame () {\n");
1900 fprintf (stream, "\tstatic struct object ob;\n");
1901 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1902 fprintf (stream, "\t}\n");
1903
1904 fprintf (stream, "static void dereg_frame () {\n");
1905 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1906 fprintf (stream, "\t}\n");
1907 }
1908
1773 fprintf (stream, "void %s() {\n", initname);
1909 fprintf (stream, "void %s() {\n", initname);
1774 if (constructors.number > 0)
1910 if (constructors.number > 0 || frames)
1775 {
1776 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
1777 write_list (stream, "\t\t", constructors.first);
1911 {
1912 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
1913 write_list (stream, "\t\t", constructors.first);
1914 if (frames)
1915 fprintf (stream, "\treg_frame,\n");
1778 fprintf (stream, "\t};\n");
1779 fprintf (stream, "\tentry_pt **p;\n");
1780 fprintf (stream, "\tif (count++ != 0) return;\n");
1916 fprintf (stream, "\t};\n");
1917 fprintf (stream, "\tentry_pt **p;\n");
1918 fprintf (stream, "\tif (count++ != 0) return;\n");
1781 fprintf (stream, "\tp = ctors + %d;\n", constructors.number);
1919 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
1782 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
1783 }
1784 else
1785 fprintf (stream, "\t++count;\n");
1786 fprintf (stream, "}\n");
1787 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1788 fprintf (stream, "void %s() {\n", fininame);
1920 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
1921 }
1922 else
1923 fprintf (stream, "\t++count;\n");
1924 fprintf (stream, "}\n");
1925 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1926 fprintf (stream, "void %s() {\n", fininame);
1789 if (destructors.number > 0)
1927 if (destructors.number > 0 || frames)
1790 {
1791 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
1792 write_list (stream, "\t\t", destructors.first);
1928 {
1929 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
1930 write_list (stream, "\t\t", destructors.first);
1931 if (frames)
1932 fprintf (stream, "\tdereg_frame,\n");
1793 fprintf (stream, "\t};\n");
1794 fprintf (stream, "\tentry_pt **p;\n");
1795 fprintf (stream, "\tif (--count != 0) return;\n");
1796 fprintf (stream, "\tp = dtors;\n");
1797 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
1933 fprintf (stream, "\t};\n");
1934 fprintf (stream, "\tentry_pt **p;\n");
1935 fprintf (stream, "\tif (--count != 0) return;\n");
1936 fprintf (stream, "\tp = dtors;\n");
1937 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
1798 destructors.number);
1938 destructors.number + frames);
1799 }
1800 fprintf (stream, "}\n");
1801
1802 if (shared_obj)
1803 {
1804 fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);
1805 fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);
1806 }
1807}
1808
1939 }
1940 fprintf (stream, "}\n");
1941
1942 if (shared_obj)
1943 {
1944 fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);
1945 fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);
1946 }
1947}
1948
1809/* Write the constructor/destructor tables. */
1949/* Write the constructor/destructor tables. */
1810
1950
1951#ifndef LD_INIT_SWITCH
1811static void
1812write_c_file_glob (stream, name)
1813 FILE *stream;
1814 char *name;
1815{
1816 /* Write the tables as C code */
1817
1952static void
1953write_c_file_glob (stream, name)
1954 FILE *stream;
1955 char *name;
1956{
1957 /* Write the tables as C code */
1958
1959 int frames = (frame_tables.number > 0);
1960
1818 fprintf (stream, "typedef void entry_pt();\n\n");
1819
1820 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1961 fprintf (stream, "typedef void entry_pt();\n\n");
1962
1963 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1821
1964
1965 if (frames)
1966 {
1967 write_list_with_asm (stream, "extern void *", frame_tables.first);
1968
1969 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1970 write_list (stream, "\t\t&", frame_tables.first);
1971 fprintf (stream, "\t0\n};\n");
1972
1973 /* This must match what's in frame.h. */
1974 fprintf (stream, "struct object {\n");
1975 fprintf (stream, " void *pc_begin;\n");
1976 fprintf (stream, " void *pc_end;\n");
1977 fprintf (stream, " void *fde_begin;\n");
1978 fprintf (stream, " void *fde_array;\n");
1979 fprintf (stream, " __SIZE_TYPE__ count;\n");
1980 fprintf (stream, " struct object *next;\n");
1981 fprintf (stream, "};\n");
1982
1983 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1984 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1985
1986 fprintf (stream, "static void reg_frame () {\n");
1987 fprintf (stream, "\tstatic struct object ob;\n");
1988 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1989 fprintf (stream, "\t}\n");
1990
1991 fprintf (stream, "static void dereg_frame () {\n");
1992 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1993 fprintf (stream, "\t}\n");
1994 }
1995
1822 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
1996 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
1823 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number);
1997 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
1824 write_list (stream, "\t", constructors.first);
1998 write_list (stream, "\t", constructors.first);
1999 if (frames)
2000 fprintf (stream, "\treg_frame,\n");
1825 fprintf (stream, "\t0\n};\n\n");
1826
1827 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1828
1829 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
2001 fprintf (stream, "\t0\n};\n\n");
2002
2003 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2004
2005 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
1830 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number);
2006 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
1831 write_list (stream, "\t", destructors.first);
2007 write_list (stream, "\t", destructors.first);
2008 if (frames)
2009 fprintf (stream, "\tdereg_frame,\n");
1832 fprintf (stream, "\t0\n};\n\n");
1833
1834 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
1835 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
1836}
2010 fprintf (stream, "\t0\n};\n\n");
2011
2012 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
2013 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
2014}
2015#endif /* ! LD_INIT_SWITCH */
1837
1838static void
1839write_c_file (stream, name)
1840 FILE *stream;
1841 char *name;
1842{
2016
2017static void
2018write_c_file (stream, name)
2019 FILE *stream;
2020 char *name;
2021{
2022 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
1843#ifndef LD_INIT_SWITCH
1844 if (! shared_obj)
1845 write_c_file_glob (stream, name);
1846 else
1847#endif
1848 write_c_file_stat (stream, name);
2023#ifndef LD_INIT_SWITCH
2024 if (! shared_obj)
2025 write_c_file_glob (stream, name);
2026 else
2027#endif
2028 write_c_file_stat (stream, name);
2029 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
1849}
1850
2030}
2031
2032#ifdef COLLECT_EXPORT_LIST
1851static void
1852write_export_file (stream)
1853 FILE *stream;
1854{
1855 struct id *list = exports.first;
1856 for (; list; list = list->next)
1857 fprintf (stream, "%s\n", list->name);
1858}
2033static void
2034write_export_file (stream)
2035 FILE *stream;
2036{
2037 struct id *list = exports.first;
2038 for (; list; list = list->next)
2039 fprintf (stream, "%s\n", list->name);
2040}
2041
2042static void
2043write_import_file (stream)
2044 FILE *stream;
2045{
2046 struct id *list = imports.first;
2047 fprintf (stream, "%s\n", "#! .");
2048 for (; list; list = list->next)
2049 fprintf (stream, "%s\n", list->name);
2050}
2051#endif
1859
1860#ifdef OBJECT_FORMAT_NONE
1861
1862/* Generic version to scan the name list of the loaded program for
1863 the symbols g++ uses for static constructors and destructors.
1864
1865 The constructor table begins at __CTOR_LIST__ and contains a count
1866 of the number of pointers (or -1 if the constructors are built in a
1867 separate section by the linker), followed by the pointers to the
1868 constructor functions, terminated with a null pointer. The
1869 destructor table has the same format, and begins at __DTOR_LIST__. */
1870
1871static void
1872scan_prog_file (prog_name, which_pass)
1873 char *prog_name;
1874 enum pass which_pass;
1875{
1876 void (*int_handler) ();
1877 void (*quit_handler) ();
1878 char *nm_argv[4];
1879 int pid;
1880 int argc = 0;
1881 int pipe_fd[2];
1882 char *p, buf[1024];
1883 FILE *inf;
1884
1885 if (which_pass == PASS_SECOND)
1886 return;
1887
2052
2053#ifdef OBJECT_FORMAT_NONE
2054
2055/* Generic version to scan the name list of the loaded program for
2056 the symbols g++ uses for static constructors and destructors.
2057
2058 The constructor table begins at __CTOR_LIST__ and contains a count
2059 of the number of pointers (or -1 if the constructors are built in a
2060 separate section by the linker), followed by the pointers to the
2061 constructor functions, terminated with a null pointer. The
2062 destructor table has the same format, and begins at __DTOR_LIST__. */
2063
2064static void
2065scan_prog_file (prog_name, which_pass)
2066 char *prog_name;
2067 enum pass which_pass;
2068{
2069 void (*int_handler) ();
2070 void (*quit_handler) ();
2071 char *nm_argv[4];
2072 int pid;
2073 int argc = 0;
2074 int pipe_fd[2];
2075 char *p, buf[1024];
2076 FILE *inf;
2077
2078 if (which_pass == PASS_SECOND)
2079 return;
2080
1888 /* If we don't have an `nm', complain. */
2081 /* If we do not have an `nm', complain. */
1889 if (nm_file_name == 0)
1890 fatal ("cannot find `nm'");
1891
1892 nm_argv[argc++] = nm_file_name;
1893 if (NM_FLAGS[0] != '\0')
1894 nm_argv[argc++] = NM_FLAGS;
1895
1896 nm_argv[argc++] = prog_name;
2082 if (nm_file_name == 0)
2083 fatal ("cannot find `nm'");
2084
2085 nm_argv[argc++] = nm_file_name;
2086 if (NM_FLAGS[0] != '\0')
2087 nm_argv[argc++] = NM_FLAGS;
2088
2089 nm_argv[argc++] = prog_name;
1897 nm_argv[argc++] = (char *)0;
2090 nm_argv[argc++] = (char *) 0;
1898
1899 if (pipe (pipe_fd) < 0)
1900 fatal_perror ("pipe");
1901
1902 inf = fdopen (pipe_fd[0], "r");
2091
2092 if (pipe (pipe_fd) < 0)
2093 fatal_perror ("pipe");
2094
2095 inf = fdopen (pipe_fd[0], "r");
1903 if (inf == (FILE *)0)
2096 if (inf == (FILE *) 0)
1904 fatal_perror ("fdopen");
1905
1906 /* Trace if needed. */
1907 if (vflag)
1908 {
1909 char **p_argv;
1910 char *str;
1911
2097 fatal_perror ("fdopen");
2098
2099 /* Trace if needed. */
2100 if (vflag)
2101 {
2102 char **p_argv;
2103 char *str;
2104
1912 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *)0; p_argv++)
2105 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
1913 fprintf (stderr, " %s", str);
1914
1915 fprintf (stderr, "\n");
1916 }
1917
1918 fflush (stdout);
1919 fflush (stderr);
1920
1921 /* Spawn child nm on pipe */
1922 pid = vfork ();
1923 if (pid == -1)
1924 {
1925#ifdef vfork
1926 fatal_perror ("fork");
1927#else
1928 fatal_perror ("vfork");
1929#endif
1930 }
1931
1932 if (pid == 0) /* child context */
1933 {
1934 /* setup stdout */
1935 if (dup2 (pipe_fd[1], 1) < 0)
1936 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
1937
1938 if (close (pipe_fd[0]) < 0)
1939 fatal_perror ("close (%d)", pipe_fd[0]);
1940
1941 if (close (pipe_fd[1]) < 0)
1942 fatal_perror ("close (%d)", pipe_fd[1]);
1943
1944 execv (nm_file_name, nm_argv);
1945 fatal_perror ("executing %s", nm_file_name);
1946 }
1947
1948 /* Parent context from here on. */
1949 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
1950#ifdef SIGQUIT
1951 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
1952#endif
1953
1954 if (close (pipe_fd[1]) < 0)
1955 fatal_perror ("close (%d)", pipe_fd[1]);
1956
1957 if (debug)
1958 fprintf (stderr, "\nnm output with constructors/destructors.\n");
1959
1960 /* Read each line of nm output. */
2106 fprintf (stderr, " %s", str);
2107
2108 fprintf (stderr, "\n");
2109 }
2110
2111 fflush (stdout);
2112 fflush (stderr);
2113
2114 /* Spawn child nm on pipe */
2115 pid = vfork ();
2116 if (pid == -1)
2117 {
2118#ifdef vfork
2119 fatal_perror ("fork");
2120#else
2121 fatal_perror ("vfork");
2122#endif
2123 }
2124
2125 if (pid == 0) /* child context */
2126 {
2127 /* setup stdout */
2128 if (dup2 (pipe_fd[1], 1) < 0)
2129 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2130
2131 if (close (pipe_fd[0]) < 0)
2132 fatal_perror ("close (%d)", pipe_fd[0]);
2133
2134 if (close (pipe_fd[1]) < 0)
2135 fatal_perror ("close (%d)", pipe_fd[1]);
2136
2137 execv (nm_file_name, nm_argv);
2138 fatal_perror ("executing %s", nm_file_name);
2139 }
2140
2141 /* Parent context from here on. */
2142 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
2143#ifdef SIGQUIT
2144 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
2145#endif
2146
2147 if (close (pipe_fd[1]) < 0)
2148 fatal_perror ("close (%d)", pipe_fd[1]);
2149
2150 if (debug)
2151 fprintf (stderr, "\nnm output with constructors/destructors.\n");
2152
2153 /* Read each line of nm output. */
1961 while (fgets (buf, sizeof buf, inf) != (char *)0)
2154 while (fgets (buf, sizeof buf, inf) != (char *) 0)
1962 {
1963 int ch, ch2;
1964 char *name, *end;
1965
1966 /* If it contains a constructor or destructor name, add the name
2155 {
2156 int ch, ch2;
2157 char *name, *end;
2158
2159 /* If it contains a constructor or destructor name, add the name
1967 to the appropriate list. */
2160 to the appropriate list. */
1968
1969 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
1970 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
1971 break;
1972
1973 if (ch != '_')
1974 continue;
1975
1976 name = p;
1977 /* Find the end of the symbol name.
2161
2162 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2163 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2164 break;
2165
2166 if (ch != '_')
2167 continue;
2168
2169 name = p;
2170 /* Find the end of the symbol name.
1978 Don't include `|', because Encore nm can tack that on the end. */
1979 for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';
2171 Do not include `|', because Encore nm can tack that on the end. */
2172 for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
1980 end++)
1981 continue;
1982
1983
1984 *end = '\0';
1985 switch (is_ctor_dtor (name))
1986 {
1987 case 1:
1988 if (which_pass != PASS_LIB)
1989 add_to_list (&constructors, name);
1990 break;
1991
1992 case 2:
1993 if (which_pass != PASS_LIB)
1994 add_to_list (&destructors, name);
1995 break;
1996
1997 case 3:
1998 if (which_pass != PASS_LIB)
1999 fatal ("init function found in object %s", prog_name);
2000#ifndef LD_INIT_SWITCH
2001 add_to_list (&constructors, name);
2002#endif
2003 break;
2004
2005 case 4:
2006 if (which_pass != PASS_LIB)
2007 fatal ("fini function found in object %s", prog_name);
2008#ifndef LD_FINI_SWITCH
2009 add_to_list (&destructors, name);
2010#endif
2011 break;
2012
2173 end++)
2174 continue;
2175
2176
2177 *end = '\0';
2178 switch (is_ctor_dtor (name))
2179 {
2180 case 1:
2181 if (which_pass != PASS_LIB)
2182 add_to_list (&constructors, name);
2183 break;
2184
2185 case 2:
2186 if (which_pass != PASS_LIB)
2187 add_to_list (&destructors, name);
2188 break;
2189
2190 case 3:
2191 if (which_pass != PASS_LIB)
2192 fatal ("init function found in object %s", prog_name);
2193#ifndef LD_INIT_SWITCH
2194 add_to_list (&constructors, name);
2195#endif
2196 break;
2197
2198 case 4:
2199 if (which_pass != PASS_LIB)
2200 fatal ("fini function found in object %s", prog_name);
2201#ifndef LD_FINI_SWITCH
2202 add_to_list (&destructors, name);
2203#endif
2204 break;
2205
2206 case 5:
2207 if (which_pass != PASS_LIB)
2208 add_to_list (&frame_tables, name);
2209
2013 default: /* not a constructor or destructor */
2014 continue;
2015 }
2016
2017 if (debug)
2018 fprintf (stderr, "\t%s\n", buf);
2019 }
2020
2021 if (debug)
2022 fprintf (stderr, "\n");
2023
2024 if (fclose (inf) != 0)
2025 fatal_perror ("fclose of pipe");
2026
2027 do_wait (nm_file_name);
2028
2029 signal (SIGINT, int_handler);
2030#ifdef SIGQUIT
2031 signal (SIGQUIT, quit_handler);
2032#endif
2033}
2034
2035#if SUNOS4_SHARED_LIBRARIES
2036
2037/* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2038 that the output file depends upon and their initialization/finalization
2039 routines, if any. */
2040
2041#include <a.out.h>
2042#include <fcntl.h>
2043#include <link.h>
2044#include <sys/mman.h>
2045#include <sys/param.h>
2210 default: /* not a constructor or destructor */
2211 continue;
2212 }
2213
2214 if (debug)
2215 fprintf (stderr, "\t%s\n", buf);
2216 }
2217
2218 if (debug)
2219 fprintf (stderr, "\n");
2220
2221 if (fclose (inf) != 0)
2222 fatal_perror ("fclose of pipe");
2223
2224 do_wait (nm_file_name);
2225
2226 signal (SIGINT, int_handler);
2227#ifdef SIGQUIT
2228 signal (SIGQUIT, quit_handler);
2229#endif
2230}
2231
2232#if SUNOS4_SHARED_LIBRARIES
2233
2234/* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2235 that the output file depends upon and their initialization/finalization
2236 routines, if any. */
2237
2238#include <a.out.h>
2239#include <fcntl.h>
2240#include <link.h>
2241#include <sys/mman.h>
2242#include <sys/param.h>
2046#include <sys/unistd.h>
2243#include
2047#include <sys/dir.h>
2048
2049/* pointers to the object file */
2050unsigned object; /* address of memory mapped file */
2051unsigned objsize; /* size of memory mapped to file */
2052char * code; /* pointer to code segment */
2053char * data; /* pointer to data segment */
2054struct nlist *symtab; /* pointer to symbol table */
2055struct link_dynamic *ld;
2056struct link_dynamic_2 *ld_2;
2057struct head libraries;
2058
2059/* Map the file indicated by NAME into memory and store its address. */
2060
2061static void
2062mapfile (name)
2063 char *name;
2064{
2065 int fp;
2066 struct stat s;
2067 if ((fp = open (name, O_RDONLY)) == -1)
2068 fatal ("unable to open file '%s'", name);
2069 if (fstat (fp, &s) == -1)
2070 fatal ("unable to stat file '%s'", name);
2071
2072 objsize = s.st_size;
2073 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2074 fp, 0);
2075 if (object == -1)
2076 fatal ("unable to mmap file '%s'", name);
2077
2078 close (fp);
2079}
2080
2081/* Helpers for locatelib. */
2082
2083static char *libname;
2084
2085static int
2086libselect (d)
2087 struct direct *d;
2088{
2089 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2090}
2091
2092/* If one file has an additional numeric extension past LIBNAME, then put
2093 that one first in the sort. If both files have additional numeric
2094 extensions, then put the one with the higher number first in the sort.
2095
2096 We must verify that the extension is numeric, because Sun saves the
2097 original versions of patched libraries with a .FCS extension. Files with
2244#include <sys/dir.h>
2245
2246/* pointers to the object file */
2247unsigned object; /* address of memory mapped file */
2248unsigned objsize; /* size of memory mapped to file */
2249char * code; /* pointer to code segment */
2250char * data; /* pointer to data segment */
2251struct nlist *symtab; /* pointer to symbol table */
2252struct link_dynamic *ld;
2253struct link_dynamic_2 *ld_2;
2254struct head libraries;
2255
2256/* Map the file indicated by NAME into memory and store its address. */
2257
2258static void
2259mapfile (name)
2260 char *name;
2261{
2262 int fp;
2263 struct stat s;
2264 if ((fp = open (name, O_RDONLY)) == -1)
2265 fatal ("unable to open file '%s'", name);
2266 if (fstat (fp, &s) == -1)
2267 fatal ("unable to stat file '%s'", name);
2268
2269 objsize = s.st_size;
2270 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2271 fp, 0);
2272 if (object == -1)
2273 fatal ("unable to mmap file '%s'", name);
2274
2275 close (fp);
2276}
2277
2278/* Helpers for locatelib. */
2279
2280static char *libname;
2281
2282static int
2283libselect (d)
2284 struct direct *d;
2285{
2286 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2287}
2288
2289/* If one file has an additional numeric extension past LIBNAME, then put
2290 that one first in the sort. If both files have additional numeric
2291 extensions, then put the one with the higher number first in the sort.
2292
2293 We must verify that the extension is numeric, because Sun saves the
2294 original versions of patched libraries with a .FCS extension. Files with
2098 invalid extensions must go last in the sort, so that they won't be used. */
2295 invalid extensions must go last in the sort, so that they will not be used. */
2099
2100static int
2101libcompare (d1, d2)
2102 struct direct **d1, **d2;
2103{
2104 int i1, i2 = strlen (libname);
2105 char *e1 = (*d1)->d_name + i2;
2106 char *e2 = (*d2)->d_name + i2;
2107
2108 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2296
2297static int
2298libcompare (d1, d2)
2299 struct direct **d1, **d2;
2300{
2301 int i1, i2 = strlen (libname);
2302 char *e1 = (*d1)->d_name + i2;
2303 char *e2 = (*d2)->d_name + i2;
2304
2305 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2109 && e1[1] && isdigit (e1[1]) && e2[1] && isdigit (e2[1]))
2306 && e1[1] && ISDIGIT (e1[1]) && e2[1] && ISDIGIT (e2[1]))
2110 {
2111 ++e1;
2112 ++e2;
2113 i1 = strtol (e1, &e1, 10);
2114 i2 = strtol (e2, &e2, 10);
2115 if (i1 != i2)
2116 return i1 - i2;
2117 }
2118
2119 if (*e1)
2120 {
2121 /* It has a valid numeric extension, prefer this one. */
2307 {
2308 ++e1;
2309 ++e2;
2310 i1 = strtol (e1, &e1, 10);
2311 i2 = strtol (e2, &e2, 10);
2312 if (i1 != i2)
2313 return i1 - i2;
2314 }
2315
2316 if (*e1)
2317 {
2318 /* It has a valid numeric extension, prefer this one. */
2122 if (*e1 == '.' && e1[1] && isdigit (e1[1]))
2319 if (*e1 == '.' && e1[1] && ISDIGIT (e1[1]))
2123 return 1;
2124 /* It has a invalid numeric extension, must prefer the other one. */
2125 else
2126 return -1;
2127 }
2128 else if (*e2)
2129 {
2130 /* It has a valid numeric extension, prefer this one. */
2320 return 1;
2321 /* It has a invalid numeric extension, must prefer the other one. */
2322 else
2323 return -1;
2324 }
2325 else if (*e2)
2326 {
2327 /* It has a valid numeric extension, prefer this one. */
2131 if (*e2 == '.' && e2[1] && isdigit (e2[1]))
2328 if (*e2 == '.' && e2[1] && ISDIGIT (e2[1]))
2132 return -1;
2133 /* It has a invalid numeric extension, must prefer the other one. */
2134 else
2135 return 1;
2136 }
2137 else
2138 return 0;
2139}
2140
2141/* Given the name NAME of a dynamic dependency, find its pathname and add
2142 it to the list of libraries. */
2143
2144static void
2145locatelib (name)
2146 char *name;
2147{
2148 static char **l;
2149 static int cnt;
2150 char buf[MAXPATHLEN];
2151 char *p, *q;
2152 char **pp;
2153
2154 if (l == 0)
2155 {
2156 char *ld_rules;
2157 char *ldr = 0;
2158 /* counting elements in array, need 1 extra for null */
2159 cnt = 1;
2160 ld_rules = (char *) (ld_2->ld_rules + code);
2161 if (ld_rules)
2162 {
2163 cnt++;
2164 for (; *ld_rules != 0; ld_rules++)
2165 if (*ld_rules == ':')
2166 cnt++;
2167 ld_rules = (char *) (ld_2->ld_rules + code);
2168 ldr = (char *) malloc (strlen (ld_rules) + 1);
2169 strcpy (ldr, ld_rules);
2170 }
2171 p = getenv ("LD_LIBRARY_PATH");
2172 q = 0;
2173 if (p)
2174 {
2175 cnt++;
2176 for (q = p ; *q != 0; q++)
2177 if (*q == ':')
2178 cnt++;
2179 q = (char *) malloc (strlen (p) + 1);
2180 strcpy (q, p);
2181 }
2182 l = (char **) malloc ((cnt + 3) * sizeof (char *));
2183 pp = l;
2184 if (ldr)
2185 {
2186 *pp++ = ldr;
2187 for (; *ldr != 0; ldr++)
2188 if (*ldr == ':')
2189 {
2190 *ldr++ = 0;
2191 *pp++ = ldr;
2192 }
2193 }
2194 if (q)
2195 {
2196 *pp++ = q;
2197 for (; *q != 0; q++)
2198 if (*q == ':')
2199 {
2200 *q++ = 0;
2201 *pp++ = q;
2202 }
2203 }
2204 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2205 *pp++ = "/lib";
2206 *pp++ = "/usr/lib";
2207 *pp++ = "/usr/local/lib";
2208 *pp = 0;
2209 }
2210 libname = name;
2211 for (pp = l; *pp != 0 ; pp++)
2212 {
2213 struct direct **namelist;
2214 int entries;
2215 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2216 {
2217 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2218 add_to_list (&libraries, buf);
2219 if (debug)
2220 fprintf (stderr, "%s\n", buf);
2221 break;
2222 }
2223 }
2224 if (*pp == 0)
2225 {
2226 if (debug)
2227 fprintf (stderr, "not found\n");
2228 else
2229 fatal ("dynamic dependency %s not found", name);
2230 }
2231}
2232
2233/* Scan the _DYNAMIC structure of the output file to find shared libraries
2234 that it depends upon and any constructors or destructors they contain. */
2235
2236static void
2237scan_libraries (prog_name)
2238 char *prog_name;
2239{
2240 struct exec *header;
2241 char *base;
2242 struct link_object *lo;
2243 char buff[MAXPATHLEN];
2244 struct id *list;
2245
2246 mapfile (prog_name);
2247 header = (struct exec *)object;
2248 if (N_BADMAG (*header))
2249 fatal ("bad magic number in file '%s'", prog_name);
2250 if (header->a_dynamic == 0)
2251 return;
2252
2253 code = (char *) (N_TXTOFF (*header) + (long) header);
2254 data = (char *) (N_DATOFF (*header) + (long) header);
2255 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2256
2257 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2258 {
2259 /* shared object */
2260 ld = (struct link_dynamic *) (symtab->n_value + code);
2261 base = code;
2262 }
2263 else
2264 {
2265 /* executable */
2266 ld = (struct link_dynamic *) data;
2267 base = code-PAGSIZ;
2268 }
2269
2270 if (debug)
2271 fprintf (stderr, "dynamic dependencies.\n");
2272
2273 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2274 for (lo = (struct link_object *) ld_2->ld_need; lo;
2275 lo = (struct link_object *) lo->lo_next)
2276 {
2277 char *name;
2278 lo = (struct link_object *) ((long) lo + code);
2279 name = (char *) (code + lo->lo_name);
2280 if (lo->lo_library)
2281 {
2282 if (debug)
2283 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2284 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2285 locatelib (buff);
2286 }
2287 else
2288 {
2289 if (debug)
2290 fprintf (stderr, "\t%s\n", name);
2291 add_to_list (&libraries, name);
2292 }
2293 }
2294
2295 if (debug)
2296 fprintf (stderr, "\n");
2297
2298 /* now iterate through the library list adding their symbols to
2299 the list. */
2300 for (list = libraries.first; list; list = list->next)
2301 scan_prog_file (list->name, PASS_LIB);
2302}
2303
2304#else /* SUNOS4_SHARED_LIBRARIES */
2305#ifdef LDD_SUFFIX
2306
2307/* Use the List Dynamic Dependencies program to find shared libraries that
2308 the output file depends upon and their initialization/finalization
2309 routines, if any. */
2310
2311static void
2312scan_libraries (prog_name)
2313 char *prog_name;
2314{
2315 static struct head libraries; /* list of shared libraries found */
2316 struct id *list;
2317 void (*int_handler) ();
2318 void (*quit_handler) ();
2319 char *ldd_argv[4];
2320 int pid;
2321 int argc = 0;
2322 int pipe_fd[2];
2323 char buf[1024];
2324 FILE *inf;
2325
2329 return -1;
2330 /* It has a invalid numeric extension, must prefer the other one. */
2331 else
2332 return 1;
2333 }
2334 else
2335 return 0;
2336}
2337
2338/* Given the name NAME of a dynamic dependency, find its pathname and add
2339 it to the list of libraries. */
2340
2341static void
2342locatelib (name)
2343 char *name;
2344{
2345 static char **l;
2346 static int cnt;
2347 char buf[MAXPATHLEN];
2348 char *p, *q;
2349 char **pp;
2350
2351 if (l == 0)
2352 {
2353 char *ld_rules;
2354 char *ldr = 0;
2355 /* counting elements in array, need 1 extra for null */
2356 cnt = 1;
2357 ld_rules = (char *) (ld_2->ld_rules + code);
2358 if (ld_rules)
2359 {
2360 cnt++;
2361 for (; *ld_rules != 0; ld_rules++)
2362 if (*ld_rules == ':')
2363 cnt++;
2364 ld_rules = (char *) (ld_2->ld_rules + code);
2365 ldr = (char *) malloc (strlen (ld_rules) + 1);
2366 strcpy (ldr, ld_rules);
2367 }
2368 p = getenv ("LD_LIBRARY_PATH");
2369 q = 0;
2370 if (p)
2371 {
2372 cnt++;
2373 for (q = p ; *q != 0; q++)
2374 if (*q == ':')
2375 cnt++;
2376 q = (char *) malloc (strlen (p) + 1);
2377 strcpy (q, p);
2378 }
2379 l = (char **) malloc ((cnt + 3) * sizeof (char *));
2380 pp = l;
2381 if (ldr)
2382 {
2383 *pp++ = ldr;
2384 for (; *ldr != 0; ldr++)
2385 if (*ldr == ':')
2386 {
2387 *ldr++ = 0;
2388 *pp++ = ldr;
2389 }
2390 }
2391 if (q)
2392 {
2393 *pp++ = q;
2394 for (; *q != 0; q++)
2395 if (*q == ':')
2396 {
2397 *q++ = 0;
2398 *pp++ = q;
2399 }
2400 }
2401 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2402 *pp++ = "/lib";
2403 *pp++ = "/usr/lib";
2404 *pp++ = "/usr/local/lib";
2405 *pp = 0;
2406 }
2407 libname = name;
2408 for (pp = l; *pp != 0 ; pp++)
2409 {
2410 struct direct **namelist;
2411 int entries;
2412 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2413 {
2414 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2415 add_to_list (&libraries, buf);
2416 if (debug)
2417 fprintf (stderr, "%s\n", buf);
2418 break;
2419 }
2420 }
2421 if (*pp == 0)
2422 {
2423 if (debug)
2424 fprintf (stderr, "not found\n");
2425 else
2426 fatal ("dynamic dependency %s not found", name);
2427 }
2428}
2429
2430/* Scan the _DYNAMIC structure of the output file to find shared libraries
2431 that it depends upon and any constructors or destructors they contain. */
2432
2433static void
2434scan_libraries (prog_name)
2435 char *prog_name;
2436{
2437 struct exec *header;
2438 char *base;
2439 struct link_object *lo;
2440 char buff[MAXPATHLEN];
2441 struct id *list;
2442
2443 mapfile (prog_name);
2444 header = (struct exec *)object;
2445 if (N_BADMAG (*header))
2446 fatal ("bad magic number in file '%s'", prog_name);
2447 if (header->a_dynamic == 0)
2448 return;
2449
2450 code = (char *) (N_TXTOFF (*header) + (long) header);
2451 data = (char *) (N_DATOFF (*header) + (long) header);
2452 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2453
2454 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2455 {
2456 /* shared object */
2457 ld = (struct link_dynamic *) (symtab->n_value + code);
2458 base = code;
2459 }
2460 else
2461 {
2462 /* executable */
2463 ld = (struct link_dynamic *) data;
2464 base = code-PAGSIZ;
2465 }
2466
2467 if (debug)
2468 fprintf (stderr, "dynamic dependencies.\n");
2469
2470 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2471 for (lo = (struct link_object *) ld_2->ld_need; lo;
2472 lo = (struct link_object *) lo->lo_next)
2473 {
2474 char *name;
2475 lo = (struct link_object *) ((long) lo + code);
2476 name = (char *) (code + lo->lo_name);
2477 if (lo->lo_library)
2478 {
2479 if (debug)
2480 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2481 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2482 locatelib (buff);
2483 }
2484 else
2485 {
2486 if (debug)
2487 fprintf (stderr, "\t%s\n", name);
2488 add_to_list (&libraries, name);
2489 }
2490 }
2491
2492 if (debug)
2493 fprintf (stderr, "\n");
2494
2495 /* now iterate through the library list adding their symbols to
2496 the list. */
2497 for (list = libraries.first; list; list = list->next)
2498 scan_prog_file (list->name, PASS_LIB);
2499}
2500
2501#else /* SUNOS4_SHARED_LIBRARIES */
2502#ifdef LDD_SUFFIX
2503
2504/* Use the List Dynamic Dependencies program to find shared libraries that
2505 the output file depends upon and their initialization/finalization
2506 routines, if any. */
2507
2508static void
2509scan_libraries (prog_name)
2510 char *prog_name;
2511{
2512 static struct head libraries; /* list of shared libraries found */
2513 struct id *list;
2514 void (*int_handler) ();
2515 void (*quit_handler) ();
2516 char *ldd_argv[4];
2517 int pid;
2518 int argc = 0;
2519 int pipe_fd[2];
2520 char buf[1024];
2521 FILE *inf;
2522
2326 /* If we don't have an `ldd', complain. */
2523 /* If we do not have an `ldd', complain. */
2327 if (ldd_file_name == 0)
2328 {
2329 error ("cannot find `ldd'");
2330 return;
2331 }
2332
2333 ldd_argv[argc++] = ldd_file_name;
2334 ldd_argv[argc++] = prog_name;
2335 ldd_argv[argc++] = (char *) 0;
2336
2337 if (pipe (pipe_fd) < 0)
2338 fatal_perror ("pipe");
2339
2340 inf = fdopen (pipe_fd[0], "r");
2341 if (inf == (FILE *) 0)
2342 fatal_perror ("fdopen");
2343
2344 /* Trace if needed. */
2345 if (vflag)
2346 {
2347 char **p_argv;
2348 char *str;
2349
2350 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2351 fprintf (stderr, " %s", str);
2352
2353 fprintf (stderr, "\n");
2354 }
2355
2356 fflush (stdout);
2357 fflush (stderr);
2358
2359 /* Spawn child ldd on pipe */
2360 pid = vfork ();
2361 if (pid == -1)
2362 {
2363#ifdef vfork
2364 fatal_perror ("fork");
2365#else
2366 fatal_perror ("vfork");
2367#endif
2368 }
2369
2370 if (pid == 0) /* child context */
2371 {
2372 /* setup stdout */
2373 if (dup2 (pipe_fd[1], 1) < 0)
2374 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2375
2376 if (close (pipe_fd[0]) < 0)
2377 fatal_perror ("close (%d)", pipe_fd[0]);
2378
2379 if (close (pipe_fd[1]) < 0)
2380 fatal_perror ("close (%d)", pipe_fd[1]);
2381
2382 execv (ldd_file_name, ldd_argv);
2383 fatal_perror ("executing %s", ldd_file_name);
2384 }
2385
2386 /* Parent context from here on. */
2387 int_handler = (void (*) ()) signal (SIGINT, SIG_IGN);
2388#ifdef SIGQUIT
2389 quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN);
2390#endif
2391
2392 if (close (pipe_fd[1]) < 0)
2393 fatal_perror ("close (%d)", pipe_fd[1]);
2394
2395 if (debug)
2396 fprintf (stderr, "\nldd output with constructors/destructors.\n");
2397
2398 /* Read each line of ldd output. */
2399 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2400 {
2401 int ch, ch2;
2402 char *name, *end, *p = buf;
2403
2524 if (ldd_file_name == 0)
2525 {
2526 error ("cannot find `ldd'");
2527 return;
2528 }
2529
2530 ldd_argv[argc++] = ldd_file_name;
2531 ldd_argv[argc++] = prog_name;
2532 ldd_argv[argc++] = (char *) 0;
2533
2534 if (pipe (pipe_fd) < 0)
2535 fatal_perror ("pipe");
2536
2537 inf = fdopen (pipe_fd[0], "r");
2538 if (inf == (FILE *) 0)
2539 fatal_perror ("fdopen");
2540
2541 /* Trace if needed. */
2542 if (vflag)
2543 {
2544 char **p_argv;
2545 char *str;
2546
2547 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2548 fprintf (stderr, " %s", str);
2549
2550 fprintf (stderr, "\n");
2551 }
2552
2553 fflush (stdout);
2554 fflush (stderr);
2555
2556 /* Spawn child ldd on pipe */
2557 pid = vfork ();
2558 if (pid == -1)
2559 {
2560#ifdef vfork
2561 fatal_perror ("fork");
2562#else
2563 fatal_perror ("vfork");
2564#endif
2565 }
2566
2567 if (pid == 0) /* child context */
2568 {
2569 /* setup stdout */
2570 if (dup2 (pipe_fd[1], 1) < 0)
2571 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2572
2573 if (close (pipe_fd[0]) < 0)
2574 fatal_perror ("close (%d)", pipe_fd[0]);
2575
2576 if (close (pipe_fd[1]) < 0)
2577 fatal_perror ("close (%d)", pipe_fd[1]);
2578
2579 execv (ldd_file_name, ldd_argv);
2580 fatal_perror ("executing %s", ldd_file_name);
2581 }
2582
2583 /* Parent context from here on. */
2584 int_handler = (void (*) ()) signal (SIGINT, SIG_IGN);
2585#ifdef SIGQUIT
2586 quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN);
2587#endif
2588
2589 if (close (pipe_fd[1]) < 0)
2590 fatal_perror ("close (%d)", pipe_fd[1]);
2591
2592 if (debug)
2593 fprintf (stderr, "\nldd output with constructors/destructors.\n");
2594
2595 /* Read each line of ldd output. */
2596 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2597 {
2598 int ch, ch2;
2599 char *name, *end, *p = buf;
2600
2404 /* Extract names of libraries and add to list. */
2601 /* Extract names of libraries and add to list. */
2405 PARSE_LDD_OUTPUT (p);
2406 if (p == 0)
2407 continue;
2408
2409 name = p;
2410 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2411 fatal ("dynamic dependency %s not found", buf);
2412
2602 PARSE_LDD_OUTPUT (p);
2603 if (p == 0)
2604 continue;
2605
2606 name = p;
2607 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2608 fatal ("dynamic dependency %s not found", buf);
2609
2413 /* Find the end of the symbol name. */
2610 /* Find the end of the symbol name. */
2414 for (end = p;
2611 for (end = p;
2415 (ch2 = *end) != '\0' && ch2 != '\n' && !isspace (ch2) && ch2 != '|';
2612 (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
2416 end++)
2417 continue;
2418 *end = '\0';
2419
2420 if (access (name, R_OK) == 0)
2421 add_to_list (&libraries, name);
2422 else
2423 fatal ("unable to open dynamic dependency '%s'", buf);
2424
2425 if (debug)
2426 fprintf (stderr, "\t%s\n", buf);
2427 }
2428 if (debug)
2429 fprintf (stderr, "\n");
2430
2431 if (fclose (inf) != 0)
2432 fatal_perror ("fclose of pipe");
2433
2434 do_wait (ldd_file_name);
2435
2436 signal (SIGINT, int_handler);
2437#ifdef SIGQUIT
2438 signal (SIGQUIT, quit_handler);
2439#endif
2440
2441 /* now iterate through the library list adding their symbols to
2442 the list. */
2443 for (list = libraries.first; list; list = list->next)
2444 scan_prog_file (list->name, PASS_LIB);
2445}
2446
2447#endif /* LDD_SUFFIX */
2448#endif /* SUNOS4_SHARED_LIBRARIES */
2449
2450#endif /* OBJECT_FORMAT_NONE */
2451
2452
2453/*
2454 * COFF specific stuff.
2455 */
2456
2457#ifdef OBJECT_FORMAT_COFF
2458
2459#if defined(EXTENDED_COFF)
2460# define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2461# define GCC_SYMENT SYMR
2462# define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
2463# define GCC_SYMINC(X) (1)
2464# define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2465# define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2466#else
2467# define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2468# define GCC_SYMENT SYMENT
2469# define GCC_OK_SYMBOL(X) \
2470 (((X).n_sclass == C_EXT) && \
2613 end++)
2614 continue;
2615 *end = '\0';
2616
2617 if (access (name, R_OK) == 0)
2618 add_to_list (&libraries, name);
2619 else
2620 fatal ("unable to open dynamic dependency '%s'", buf);
2621
2622 if (debug)
2623 fprintf (stderr, "\t%s\n", buf);
2624 }
2625 if (debug)
2626 fprintf (stderr, "\n");
2627
2628 if (fclose (inf) != 0)
2629 fatal_perror ("fclose of pipe");
2630
2631 do_wait (ldd_file_name);
2632
2633 signal (SIGINT, int_handler);
2634#ifdef SIGQUIT
2635 signal (SIGQUIT, quit_handler);
2636#endif
2637
2638 /* now iterate through the library list adding their symbols to
2639 the list. */
2640 for (list = libraries.first; list; list = list->next)
2641 scan_prog_file (list->name, PASS_LIB);
2642}
2643
2644#endif /* LDD_SUFFIX */
2645#endif /* SUNOS4_SHARED_LIBRARIES */
2646
2647#endif /* OBJECT_FORMAT_NONE */
2648
2649
2650/*
2651 * COFF specific stuff.
2652 */
2653
2654#ifdef OBJECT_FORMAT_COFF
2655
2656#if defined(EXTENDED_COFF)
2657# define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2658# define GCC_SYMENT SYMR
2659# define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
2660# define GCC_SYMINC(X) (1)
2661# define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2662# define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2663#else
2664# define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2665# define GCC_SYMENT SYMENT
2666# define GCC_OK_SYMBOL(X) \
2667 (((X).n_sclass == C_EXT) && \
2471 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
2472 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
2668 ((X).n_scnum > N_UNDEF) && \
2669 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
2670 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
2671# define GCC_UNDEF_SYMBOL(X) \
2672 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2473# define GCC_SYMINC(X) ((X).n_numaux+1)
2474# define GCC_SYMZERO(X) 0
2673# define GCC_SYMINC(X) ((X).n_numaux+1)
2674# define GCC_SYMZERO(X) 0
2475# define GCC_CHECK_HDR(X) (1)
2675# define GCC_CHECK_HDR(X) \
2676 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2677 || (HEADER (X).f_magic == 0757 && aix64_flag))
2476#endif
2477
2478extern char *ldgetname ();
2479
2480/* COFF version to scan the name list of the loaded program for
2481 the symbols g++ uses for static constructors and destructors.
2482
2483 The constructor table begins at __CTOR_LIST__ and contains a count
2484 of the number of pointers (or -1 if the constructors are built in a
2485 separate section by the linker), followed by the pointers to the
2486 constructor functions, terminated with a null pointer. The
2487 destructor table has the same format, and begins at __DTOR_LIST__. */
2488
2489static void
2490scan_prog_file (prog_name, which_pass)
2491 char *prog_name;
2492 enum pass which_pass;
2493{
2494 LDFILE *ldptr = NULL;
2495 int sym_index, sym_count;
2678#endif
2679
2680extern char *ldgetname ();
2681
2682/* COFF version to scan the name list of the loaded program for
2683 the symbols g++ uses for static constructors and destructors.
2684
2685 The constructor table begins at __CTOR_LIST__ and contains a count
2686 of the number of pointers (or -1 if the constructors are built in a
2687 separate section by the linker), followed by the pointers to the
2688 constructor functions, terminated with a null pointer. The
2689 destructor table has the same format, and begins at __DTOR_LIST__. */
2690
2691static void
2692scan_prog_file (prog_name, which_pass)
2693 char *prog_name;
2694 enum pass which_pass;
2695{
2696 LDFILE *ldptr = NULL;
2697 int sym_index, sym_count;
2698 int is_shared = 0;
2699#ifdef COLLECT_EXPORT_LIST
2700 /* Should we generate an import list for given prog_name? */
2701 int import_flag = (which_pass == PASS_OBJ ? 0 : use_import_list (prog_name));
2702#endif
2496
2497 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2498 return;
2499
2703
2704 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2705 return;
2706
2500 if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
2501 fatal ("%s: can't open as COFF file", prog_name);
2502
2503 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
2504 fatal ("%s: not a COFF file", prog_name);
2707#ifdef COLLECT_EXPORT_LIST
2708 /* We do not need scanning for some standard C libraries. */
2709 if (which_pass == PASS_FIRST && ignore_library (prog_name))
2710 return;
2505
2711
2506 if (GCC_CHECK_HDR (ldptr))
2712 /* On AIX we have a loop, because there is not much difference
2713 between an object and an archive. This trick allows us to
2714 eliminate scan_libraries() function. */
2715 do
2507 {
2716 {
2508 sym_count = GCC_SYMBOLS (ldptr);
2509 sym_index = GCC_SYMZERO (ldptr);
2510 while (sym_index < sym_count)
2717#endif
2718 if ((ldptr = ldopen (prog_name, ldptr)) != NULL)
2511 {
2719 {
2512 GCC_SYMENT symbol;
2720 if (! MY_ISCOFF (HEADER (ldptr).f_magic))
2721 fatal ("%s: not a COFF file", prog_name);
2513
2722
2514 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2515 break;
2516 sym_index += GCC_SYMINC (symbol);
2517
2518 if (GCC_OK_SYMBOL (symbol))
2723 if (GCC_CHECK_HDR (ldptr))
2519 {
2724 {
2520 char *name;
2725 sym_count = GCC_SYMBOLS (ldptr);
2726 sym_index = GCC_SYMZERO (ldptr);
2521
2727
2522 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2523 continue; /* should never happen */
2728#ifdef COLLECT_EXPORT_LIST
2729 /* Is current archive member a shared object? */
2730 is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2731#endif
2524
2732
2733 while (sym_index < sym_count)
2734 {
2735 GCC_SYMENT symbol;
2736
2737 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2738 break;
2739 sym_index += GCC_SYMINC (symbol);
2740
2741 if (GCC_OK_SYMBOL (symbol))
2742 {
2743 char *name;
2744
2745 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2746 continue; /* should never happen */
2747
2525#ifdef XCOFF_DEBUGGING_INFO
2748#ifdef XCOFF_DEBUGGING_INFO
2526 /* All AIX function names have a duplicate entry beginning
2527 with a dot. */
2528 if (*name == '.')
2529 ++name;
2749 /* All AIX function names have a duplicate entry
2750 beginning with a dot. */
2751 if (*name == '.')
2752 ++name;
2530#endif
2531
2753#endif
2754
2532 switch (is_ctor_dtor (name))
2533 {
2534 case 1:
2535 add_to_list (&constructors, name);
2536 if (which_pass == PASS_OBJ)
2537 add_to_list (&exports, name);
2538 break;
2755 switch (is_ctor_dtor (name))
2756 {
2757 case 1:
2758 if (! is_shared) add_to_list (&constructors, name);
2759#ifdef COLLECT_EXPORT_LIST
2760 if (which_pass == PASS_OBJ)
2761 add_to_list (&exports, name);
2762 /* If this symbol was undefined and we are building
2763 an import list, we should add a symbol to this
2764 list. */
2765 else
2766 if (import_flag
2767 && is_in_list (name, undefined.first))
2768 add_to_list (&imports, name);
2769#endif
2770 break;
2539
2771
2540 case 2:
2541 add_to_list (&destructors, name);
2542 if (which_pass == PASS_OBJ)
2543 add_to_list (&exports, name);
2544 break;
2772 case 2:
2773 if (! is_shared) add_to_list (&destructors, name);
2774#ifdef COLLECT_EXPORT_LIST
2775 if (which_pass == PASS_OBJ)
2776 add_to_list (&exports, name);
2777 /* If this symbol was undefined and we are building
2778 an import list, we should add a symbol to this
2779 list. */
2780 else
2781 if (import_flag
2782 && is_in_list (name, undefined.first))
2783 add_to_list (&imports, name);
2784#endif
2785 break;
2545
2786
2546 default: /* not a constructor or destructor */
2547 continue;
2548 }
2787#ifdef COLLECT_EXPORT_LIST
2788 case 3:
2789 if (is_shared)
2790 add_to_list (&constructors, name);
2791 break;
2549
2792
2793 case 4:
2794 if (is_shared)
2795 add_to_list (&destructors, name);
2796 break;
2797#endif
2798
2799 default: /* not a constructor or destructor */
2800#ifdef COLLECT_EXPORT_LIST
2801 /* If we are building a shared object on AIX we need
2802 to explicitly export all global symbols or add
2803 them to import list. */
2804 if (shared_obj)
2805 {
2806 if (which_pass == PASS_OBJ && (! export_flag))
2807 add_to_list (&exports, name);
2808 else if (! is_shared && which_pass == PASS_FIRST
2809 && import_flag
2810 && is_in_list(name, undefined.first))
2811 add_to_list (&imports, name);
2812 }
2813#endif
2814 continue;
2815 }
2816
2550#if !defined(EXTENDED_COFF)
2817#if !defined(EXTENDED_COFF)
2551 if (debug)
2552 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2553 symbol.n_scnum, symbol.n_sclass,
2554 (symbol.n_type ? "0" : ""), symbol.n_type,
2555 name);
2818 if (debug)
2819 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2820 symbol.n_scnum, symbol.n_sclass,
2821 (symbol.n_type ? "0" : ""), symbol.n_type,
2822 name);
2556#else
2823#else
2557 if (debug)
2558 fprintf (stderr, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
2559 symbol.iss, symbol.value, symbol.index, name);
2824 if (debug)
2825 fprintf (stderr,
2826 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2827 symbol.iss, (long) symbol.value, symbol.index, name);
2560#endif
2828#endif
2829 }
2830#ifdef COLLECT_EXPORT_LIST
2831 /* If we are building a shared object we should collect
2832 information about undefined symbols for later
2833 import list generation. */
2834 else if (shared_obj && GCC_UNDEF_SYMBOL (symbol))
2835 {
2836 char *name;
2837
2838 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2839 continue; /* should never happen */
2840
2841 /* All AIX function names have a duplicate entry
2842 beginning with a dot. */
2843 if (*name == '.')
2844 ++name;
2845 add_to_list (&undefined, name);
2846 }
2847#endif
2848 }
2561 }
2849 }
2850#ifdef COLLECT_EXPORT_LIST
2851 else
2852 {
2853 /* If archive contains both 32-bit and 64-bit objects,
2854 we want to skip objects in other mode so mismatch normal. */
2855 if (debug)
2856 fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
2857 prog_name, HEADER (ldptr).f_magic, aix64_flag);
2858 }
2859#endif
2562 }
2860 }
2861 else
2862 {
2863 fatal ("%s: cannot open as COFF file", prog_name);
2864 }
2865#ifdef COLLECT_EXPORT_LIST
2866 /* On AIX loop continues while there are more members in archive. */
2563 }
2867 }
2564
2868 while (ldclose (ldptr) == FAILURE);
2869#else
2870 /* Otherwise we simply close ldptr. */
2565 (void) ldclose(ldptr);
2871 (void) ldclose(ldptr);
2872#endif
2566}
2567
2873}
2874
2568#ifdef XCOFF_SCAN_LIBS
2569/* Scan imported AIX libraries for GCC static ctors and dtors.
2570 FIXME: it is possible to link an executable without the actual import
2571 library by using an "import file" - a text file listing symbols
2572 exported by a library. To support this, we would have to scan
2573 import files as well as actual shared binaries to find GCC ctors.
2574 TODO: use memory mapping instead of 'ld' routines, files are already
2575 memory mapped, but we could eliminate the extra in-memory copies.
2576 Is it worth the effort? */
2577
2875
2578static void
2579scan_libraries (prog_name)
2876#ifdef COLLECT_EXPORT_LIST
2877
2878/* This new function is used to decide whether we should
2879 generate import list for an object or to use it directly. */
2880static int
2881use_import_list (prog_name)
2580 char *prog_name;
2581{
2882 char *prog_name;
2883{
2582 LDFILE *ldptr;
2583 SCNHDR ldsh;
2584 static struct path_prefix libpath; /* we should only do this once */
2884 char *p;
2585
2885
2586 if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
2587 fatal ("%s: can't open as COFF file", prog_name);
2588
2589 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
2590 fatal ("%s: not a COFF file", prog_name);
2886 /* If we do not build a shared object then import list should not be used. */
2887 if (! shared_obj) return 0;
2591
2888
2592 /* find and read loader section */
2593 if (ldnshread (ldptr, _LOADER, &ldsh))
2594 {
2595 LDHDR ldh;
2596 char *impbuf;
2597 int entry;
2889 /* Currently we check only for libgcc, but this can be changed in future. */
2890 p = strstr (prog_name, "libgcc.a");
2891 if (p != 0 && (strlen (p) == sizeof ("libgcc.a") - 1))
2892 return 1;
2893 return 0;
2894}
2598
2895
2599 FSEEK (ldptr, ldsh.s_scnptr, BEGINNING);
2600 FREAD (&ldh, sizeof (ldh), 1, ldptr);
2601 /* read import library list */
2602 impbuf = alloca (ldh.l_istlen);
2603 FSEEK (ldptr, ldh.l_impoff + ldsh.s_scnptr, BEGINNING);
2604 FREAD (impbuf, ldh.l_istlen, 1, ldptr);
2896/* Given a library name without "lib" prefix, this function
2897 returns a full library name including a path. */
2898static char *
2899resolve_lib_name (name)
2900 char *name;
2901{
2902 char *lib_buf;
2903 int i, j, l = 0;
2605
2904
2606 if (debug)
2607 fprintf (stderr, "LIBPATH=%s\n", impbuf);
2608 prefix_from_string (impbuf, &libpath);
2905 for (i = 0; libpaths[i]; i++)
2906 if (libpaths[i]->max_len > l)
2907 l = libpaths[i]->max_len;
2609
2908
2610 /* skip LIBPATH and empty base and member fields */
2611 impbuf += strlen (impbuf) + 3;
2612 for (entry = 1; entry < ldh.l_nimpid; ++entry)
2613 {
2614 char *impath = impbuf;
2615 char *implib = impath + strlen (impath) + 1;
2616 char *impmem = implib + strlen (implib) + 1;
2617 char *soname = NULL;
2618 char *trial;
2619 int pathlen;
2620 LDFILE *libptr = NULL;
2621 struct prefix_list *pl;
2622 ARCHDR ah;
2909 lib_buf = xmalloc (l + strlen(name) + 10);
2623
2910
2624 impbuf = impmem + strlen (impmem) + 1;
2625 if (debug)
2626 fprintf (stderr, "PATH+BASE=%s%s\n", impath, implib);
2627 /* Skip AIX kernel exports */
2628 if (*impath == '/' && *(impath+1) == '\0'
2629 && strcmp (implib, "unix") == 0)
2630 continue;
2631 pathlen = strlen (impath);
2632 trial = alloca (MAX (pathlen + 1, libpath.max_len)
2633 + strlen (implib) + 1);
2634 if (*impath)
2911 for (i = 0; libpaths[i]; i++)
2912 {
2913 struct prefix_list *list = libpaths[i]->plist;
2914 for (; list; list = list->next)
2915 {
2916 for (j = 0; libexts[j]; j++)
2635 {
2917 {
2636 strcpy (trial, impath);
2637 if (impath[pathlen - 1] != '/')
2638 trial[pathlen++] = '/';
2639 strcpy (trial + pathlen, implib);
2640 if (access (trial, R_OK) == 0)
2641 soname = trial;
2642 }
2643 else
2644 for (pl = libpath.plist; pl; pl = pl->next)
2645 {
2646 strcpy (trial, pl->prefix);
2647 strcat (trial, implib);
2648 if (access (trial, R_OK) == 0)
2649 {
2650 soname = trial;
2651 break;
2652 }
2653 }
2654
2655 if (! soname)
2656 fatal ("%s: library not found", implib);
2657 if (debug)
2658 if (*impmem)
2659 fprintf (stderr, "%s (%s)\n", soname, impmem);
2660 else
2661 fprintf (stderr, "%s\n", soname);
2662
2663 do
2664 {
2665 /* scan imported shared objects for GCC GLOBAL ctors */
2666 short type;
2667 if ((libptr = ldopen (soname, libptr)) == NULL)
2668 fatal ("%s: can't open import library", soname);
2669 if (TYPE (libptr) == ARTYPE)
2918 /* The following lines are needed because path_prefix list
2919 may contain directories both with trailing '/' and
2920 without it. */
2921 char *p = "";
2922 if (list->prefix[strlen(list->prefix)-1] != '/')
2923 p = "/";
2924 sprintf (lib_buf, "%s%slib%s.%s",
2925 list->prefix, p, name, libexts[j]);
2926if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
2927 if (file_exists (lib_buf))
2670 {
2928 {
2671 LDFILE *memptr;
2672 if (! *impmem)
2673 fatal ("%s: no archive member specified", soname);
2674 ldahread (libptr, &ah);
2675 if (strcmp (ah.ar_name, impmem))
2676 continue;
2929if (debug) fprintf (stderr, "found: %s\n", lib_buf);
2930 return (lib_buf);
2677 }
2931 }
2678 type = HEADER (libptr).f_magic;
2679 if (HEADER (libptr).f_flags & F_SHROBJ)
2680 {
2681 SCNHDR soldsh;
2682 LDHDR soldh;
2683 long symcnt, i;
2684 char *ldstrings;
2685 LDSYM *lsyms;
2686 if (!ldnshread (libptr, _LOADER, &soldsh))
2687 fatal ("%s: not an import library", soname);
2688 FSEEK (libptr, soldsh.s_scnptr, BEGINNING);
2689 if (FREAD (&soldh, sizeof (soldh), 1, libptr) != 1)
2690 fatal ("%s: can't read loader section", soname);
2691 /*fprintf (stderr, "\tscanning %s\n", soname);*/
2692 symcnt = soldh.l_nsyms;
2693 lsyms = (LDSYM*) alloca (symcnt * sizeof (*lsyms));
2694 symcnt = FREAD (lsyms, sizeof (*lsyms), symcnt, libptr);
2695 ldstrings = alloca (soldh.l_stlen);
2696 FSEEK (libptr, soldsh.s_scnptr+soldh.l_stoff, BEGINNING);
2697 FREAD (ldstrings, soldh.l_stlen, 1, libptr);
2698 for (i = 0; i < symcnt; ++i)
2699 {
2700 LDSYM *l = lsyms + i;
2701 if (LDR_EXPORT (*l))
2702 {
2703 char *expname = 0;
2704 if (l->l_zeroes)
2705 expname = l->l_name;
2706 else if (l->l_offset < soldh.l_stlen)
2707 expname = ldstrings + l->l_offset;
2708 switch (is_ctor_dtor (expname))
2709 {
2710 case 3:
2711 if (debug)
2712 fprintf (stderr, "\t%s\n", expname);
2713 add_to_list (&constructors, expname);
2714 break;
2715
2716 case 4:
2717 add_to_list (&destructors, expname);
2718 break;
2719
2720 default: /* not a constructor or destructor */
2721 continue;
2722 }
2723 }
2724 }
2725 }
2726 else
2727 fprintf (stderr, "%s: type = %04X flags = %04X\n",
2728 ah.ar_name, type, HEADER (libptr).f_flags);
2729 }
2932 }
2730 while (ldclose (libptr) == FAILURE);
2731 /* printf (stderr, "closed %s\n", soname); */
2732 }
2733 }
2933 }
2934 }
2935 if (debug)
2936 fprintf (stderr, "not found\n");
2937 else
2938 fatal ("Library lib%s not found", name);
2939 return (NULL);
2734}
2940}
2735#endif /* XCOFF_SCAN_LIBS */
2736
2941
2942/* Array of standard AIX libraries which should not
2943 be scanned for ctors/dtors. */
2944static char* aix_std_libs[] = {
2945 "/unix",
2946 "/lib/libc.a",
2947 "/lib/libc_r.a",
2948 "/usr/lib/libc.a",
2949 "/usr/lib/libc_r.a",
2950 "/usr/lib/threads/libc.a",
2951 "/usr/ccs/lib/libc.a",
2952 "/usr/ccs/lib/libc_r.a",
2953 NULL
2954};
2955
2956/* This function checks the filename and returns 1
2957 if this name matches the location of a standard AIX library. */
2958static int
2959ignore_library (name)
2960 char *name;
2961{
2962 char **p = &aix_std_libs[0];
2963 while (*p++ != NULL)
2964 if (! strcmp (name, *p)) return 1;
2965 return 0;
2966}
2967
2968#endif
2969
2737#endif /* OBJECT_FORMAT_COFF */
2738
2739
2740/*
2741 * OSF/rose specific stuff.
2742 */
2743
2744#ifdef OBJECT_FORMAT_ROSE
2745
2746/* Union of the various load commands */
2747
2748typedef union load_union
2749{
2750 ldc_header_t hdr; /* common header */
2751 load_cmd_map_command_t map; /* map indexing other load cmds */
2752 interpreter_command_t iprtr; /* interpreter pathname */
2753 strings_command_t str; /* load commands strings section */
2754 region_command_t region; /* region load command */
2755 reloc_command_t reloc; /* relocation section */
2756 package_command_t pkg; /* package load command */
2757 symbols_command_t sym; /* symbol sections */
2758 entry_command_t ent; /* program start section */
2759 gen_info_command_t info; /* object information */
2760 func_table_command_t func; /* function constructors/destructors */
2761} load_union_t;
2762
2763/* Structure to point to load command and data section in memory. */
2764
2765typedef struct load_all
2766{
2767 load_union_t *load; /* load command */
2768 char *section; /* pointer to section */
2769} load_all_t;
2770
2771/* Structure to contain information about a file mapped into memory. */
2772
2773struct file_info
2774{
2775 char *start; /* start of map */
2776 char *name; /* filename */
2777 long size; /* size of the file */
2778 long rounded_size; /* size rounded to page boundary */
2779 int fd; /* file descriptor */
2780 int rw; /* != 0 if opened read/write */
2781 int use_mmap; /* != 0 if mmap'ed */
2782};
2783
2784extern int decode_mach_o_hdr ();
2785extern int encode_mach_o_hdr ();
2786
2787static void add_func_table PROTO((mo_header_t *, load_all_t *,
2788 symbol_info_t *, int));
2789static void print_header PROTO((mo_header_t *));
2970#endif /* OBJECT_FORMAT_COFF */
2971
2972
2973/*
2974 * OSF/rose specific stuff.
2975 */
2976
2977#ifdef OBJECT_FORMAT_ROSE
2978
2979/* Union of the various load commands */
2980
2981typedef union load_union
2982{
2983 ldc_header_t hdr; /* common header */
2984 load_cmd_map_command_t map; /* map indexing other load cmds */
2985 interpreter_command_t iprtr; /* interpreter pathname */
2986 strings_command_t str; /* load commands strings section */
2987 region_command_t region; /* region load command */
2988 reloc_command_t reloc; /* relocation section */
2989 package_command_t pkg; /* package load command */
2990 symbols_command_t sym; /* symbol sections */
2991 entry_command_t ent; /* program start section */
2992 gen_info_command_t info; /* object information */
2993 func_table_command_t func; /* function constructors/destructors */
2994} load_union_t;
2995
2996/* Structure to point to load command and data section in memory. */
2997
2998typedef struct load_all
2999{
3000 load_union_t *load; /* load command */
3001 char *section; /* pointer to section */
3002} load_all_t;
3003
3004/* Structure to contain information about a file mapped into memory. */
3005
3006struct file_info
3007{
3008 char *start; /* start of map */
3009 char *name; /* filename */
3010 long size; /* size of the file */
3011 long rounded_size; /* size rounded to page boundary */
3012 int fd; /* file descriptor */
3013 int rw; /* != 0 if opened read/write */
3014 int use_mmap; /* != 0 if mmap'ed */
3015};
3016
3017extern int decode_mach_o_hdr ();
3018extern int encode_mach_o_hdr ();
3019
3020static void add_func_table PROTO((mo_header_t *, load_all_t *,
3021 symbol_info_t *, int));
3022static void print_header PROTO((mo_header_t *));
2790static void print_load_command PROTO((load_union_t*, size_t, int));
3023static void print_load_command PROTO((load_union_t *, size_t, int));
2791static void bad_header PROTO((int));
2792static struct file_info *read_file PROTO((char *, int, int));
2793static void end_file PROTO((struct file_info *));
2794
2795/* OSF/rose specific version to scan the name list of the loaded
2796 program for the symbols g++ uses for static constructors and
2797 destructors.
2798
2799 The constructor table begins at __CTOR_LIST__ and contains a count
2800 of the number of pointers (or -1 if the constructors are built in a
2801 separate section by the linker), followed by the pointers to the
2802 constructor functions, terminated with a null pointer. The
2803 destructor table has the same format, and begins at __DTOR_LIST__. */
2804
2805static void
2806scan_prog_file (prog_name, which_pass)
2807 char *prog_name;
2808 enum pass which_pass;
2809{
2810 char *obj;
2811 mo_header_t hdr;
2812 load_all_t *load_array;
2813 load_all_t *load_end;
2814 load_all_t *load_cmd;
2815 int symbol_load_cmds;
2816 off_t offset;
2817 int i;
2818 int num_syms;
2819 int status;
2820 char *str_sect;
2821 struct file_info *obj_file;
2822 int prog_fd;
2823 mo_lcid_t cmd_strings = -1;
2824 symbol_info_t *main_sym = 0;
2825 int rw = (which_pass != PASS_FIRST);
2826
2827 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
2828 if (prog_fd < 0)
3024static void bad_header PROTO((int));
3025static struct file_info *read_file PROTO((char *, int, int));
3026static void end_file PROTO((struct file_info *));
3027
3028/* OSF/rose specific version to scan the name list of the loaded
3029 program for the symbols g++ uses for static constructors and
3030 destructors.
3031
3032 The constructor table begins at __CTOR_LIST__ and contains a count
3033 of the number of pointers (or -1 if the constructors are built in a
3034 separate section by the linker), followed by the pointers to the
3035 constructor functions, terminated with a null pointer. The
3036 destructor table has the same format, and begins at __DTOR_LIST__. */
3037
3038static void
3039scan_prog_file (prog_name, which_pass)
3040 char *prog_name;
3041 enum pass which_pass;
3042{
3043 char *obj;
3044 mo_header_t hdr;
3045 load_all_t *load_array;
3046 load_all_t *load_end;
3047 load_all_t *load_cmd;
3048 int symbol_load_cmds;
3049 off_t offset;
3050 int i;
3051 int num_syms;
3052 int status;
3053 char *str_sect;
3054 struct file_info *obj_file;
3055 int prog_fd;
3056 mo_lcid_t cmd_strings = -1;
3057 symbol_info_t *main_sym = 0;
3058 int rw = (which_pass != PASS_FIRST);
3059
3060 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
3061 if (prog_fd < 0)
2829 fatal_perror ("can't read %s", prog_name);
3062 fatal_perror ("cannot read %s", prog_name);
2830
2831 obj_file = read_file (prog_name, prog_fd, rw);
2832 obj = obj_file->start;
2833
2834 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
2835 if (status != MO_HDR_CONV_SUCCESS)
2836 bad_header (status);
2837
2838
2839 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
2840 since the hardware will automatically swap bytes for us on loading little endian
2841 integers. */
2842
2843#ifndef CROSS_COMPILE
2844 if (hdr.moh_magic != MOH_MAGIC_MSB
2845 || hdr.moh_header_version != MOH_HEADER_VERSION
2846 || hdr.moh_byte_order != OUR_BYTE_ORDER
2847 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
2848 || hdr.moh_cpu_type != OUR_CPU_TYPE
2849 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
2850 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
2851 {
2852 fatal ("incompatibilities between object file & expected values");
2853 }
2854#endif
2855
2856 if (debug)
2857 print_header (&hdr);
2858
2859 offset = hdr.moh_first_cmd_off;
2860 load_end = load_array
2861 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
2862
2863 /* Build array of load commands, calculating the offsets */
2864 for (i = 0; i < hdr.moh_n_load_cmds; i++)
2865 {
2866 load_union_t *load_hdr; /* load command header */
2867
2868 load_cmd = load_end++;
2869 load_hdr = (load_union_t *) (obj + offset);
2870
2871 /* If modifying the program file, copy the header. */
2872 if (rw)
2873 {
2874 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
2875 bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size);
2876 load_hdr = ptr;
2877
2878 /* null out old command map, because we will rewrite at the end. */
2879 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
2880 {
2881 cmd_strings = ptr->map.lcm_ld_cmd_strings;
2882 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
2883 }
2884 }
2885
2886 load_cmd->load = load_hdr;
2887 if (load_hdr->hdr.ldci_section_off > 0)
2888 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
2889
2890 if (debug)
2891 print_load_command (load_hdr, offset, i);
2892
2893 offset += load_hdr->hdr.ldci_cmd_size;
2894 }
2895
2896 /* If the last command is the load command map and is not undefined,
2897 decrement the count of load commands. */
2898 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
2899 {
2900 load_end--;
2901 hdr.moh_n_load_cmds--;
2902 }
2903
2904 /* Go through and process each symbol table section. */
2905 symbol_load_cmds = 0;
2906 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
2907 {
2908 load_union_t *load_hdr = load_cmd->load;
2909
2910 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
2911 {
2912 symbol_load_cmds++;
2913
2914 if (debug)
2915 {
2916 char *kind = "unknown";
2917
2918 switch (load_hdr->sym.symc_kind)
2919 {
2920 case SYMC_IMPORTS: kind = "imports"; break;
2921 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
2922 case SYMC_STABS: kind = "stabs"; break;
2923 }
2924
2925 fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
2926 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
2927 }
2928
2929 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
2930 continue;
2931
2932 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
3063
3064 obj_file = read_file (prog_name, prog_fd, rw);
3065 obj = obj_file->start;
3066
3067 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
3068 if (status != MO_HDR_CONV_SUCCESS)
3069 bad_header (status);
3070
3071
3072 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3073 since the hardware will automatically swap bytes for us on loading little endian
3074 integers. */
3075
3076#ifndef CROSS_COMPILE
3077 if (hdr.moh_magic != MOH_MAGIC_MSB
3078 || hdr.moh_header_version != MOH_HEADER_VERSION
3079 || hdr.moh_byte_order != OUR_BYTE_ORDER
3080 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
3081 || hdr.moh_cpu_type != OUR_CPU_TYPE
3082 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
3083 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
3084 {
3085 fatal ("incompatibilities between object file & expected values");
3086 }
3087#endif
3088
3089 if (debug)
3090 print_header (&hdr);
3091
3092 offset = hdr.moh_first_cmd_off;
3093 load_end = load_array
3094 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
3095
3096 /* Build array of load commands, calculating the offsets */
3097 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3098 {
3099 load_union_t *load_hdr; /* load command header */
3100
3101 load_cmd = load_end++;
3102 load_hdr = (load_union_t *) (obj + offset);
3103
3104 /* If modifying the program file, copy the header. */
3105 if (rw)
3106 {
3107 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
3108 bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size);
3109 load_hdr = ptr;
3110
3111 /* null out old command map, because we will rewrite at the end. */
3112 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
3113 {
3114 cmd_strings = ptr->map.lcm_ld_cmd_strings;
3115 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
3116 }
3117 }
3118
3119 load_cmd->load = load_hdr;
3120 if (load_hdr->hdr.ldci_section_off > 0)
3121 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
3122
3123 if (debug)
3124 print_load_command (load_hdr, offset, i);
3125
3126 offset += load_hdr->hdr.ldci_cmd_size;
3127 }
3128
3129 /* If the last command is the load command map and is not undefined,
3130 decrement the count of load commands. */
3131 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
3132 {
3133 load_end--;
3134 hdr.moh_n_load_cmds--;
3135 }
3136
3137 /* Go through and process each symbol table section. */
3138 symbol_load_cmds = 0;
3139 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
3140 {
3141 load_union_t *load_hdr = load_cmd->load;
3142
3143 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
3144 {
3145 symbol_load_cmds++;
3146
3147 if (debug)
3148 {
3149 char *kind = "unknown";
3150
3151 switch (load_hdr->sym.symc_kind)
3152 {
3153 case SYMC_IMPORTS: kind = "imports"; break;
3154 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
3155 case SYMC_STABS: kind = "stabs"; break;
3156 }
3157
3158 fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3159 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
3160 }
3161
3162 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
3163 continue;
3164
3165 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
2933 if (str_sect == (char *)0)
3166 if (str_sect == (char *) 0)
2934 fatal ("string section missing");
2935
3167 fatal ("string section missing");
3168
2936 if (load_cmd->section == (char *)0)
3169 if (load_cmd->section == (char *) 0)
2937 fatal ("section pointer missing");
2938
2939 num_syms = load_hdr->sym.symc_nentries;
2940 for (i = 0; i < num_syms; i++)
2941 {
2942 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
2943 char *name = sym->si_name.symbol_name + str_sect;
2944
2945 if (name[0] != '_')
2946 continue;
2947
2948 if (rw)
2949 {
2950 char *n = name + strlen (name) - strlen (NAME__MAIN);
2951
2952 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
2953 continue;
2954 while (n != name)
2955 if (*--n != '_')
2956 continue;
2957
2958 main_sym = sym;
2959 }
2960 else
2961 {
2962 switch (is_ctor_dtor (name))
2963 {
2964 case 1:
2965 add_to_list (&constructors, name);
2966 break;
2967
2968 case 2:
2969 add_to_list (&destructors, name);
2970 break;
2971
2972 default: /* not a constructor or destructor */
2973 continue;
2974 }
2975 }
2976
2977 if (debug)
2978 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
2979 sym->si_type, sym->si_sc_type, sym->si_flags, name);
2980 }
2981 }
2982 }
2983
2984 if (symbol_load_cmds == 0)
2985 fatal ("no symbol table found");
2986
2987 /* Update the program file now, rewrite header and load commands. At present,
2988 we assume that there is enough space after the last load command to insert
2989 one more. Since the first section written out is page aligned, and the
2990 number of load commands is small, this is ok for the present. */
2991
2992 if (rw)
2993 {
2994 load_union_t *load_map;
2995 size_t size;
2996
2997 if (cmd_strings == -1)
2998 fatal ("no cmd_strings found");
2999
3000 /* Add __main to initializer list.
3170 fatal ("section pointer missing");
3171
3172 num_syms = load_hdr->sym.symc_nentries;
3173 for (i = 0; i < num_syms; i++)
3174 {
3175 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
3176 char *name = sym->si_name.symbol_name + str_sect;
3177
3178 if (name[0] != '_')
3179 continue;
3180
3181 if (rw)
3182 {
3183 char *n = name + strlen (name) - strlen (NAME__MAIN);
3184
3185 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
3186 continue;
3187 while (n != name)
3188 if (*--n != '_')
3189 continue;
3190
3191 main_sym = sym;
3192 }
3193 else
3194 {
3195 switch (is_ctor_dtor (name))
3196 {
3197 case 1:
3198 add_to_list (&constructors, name);
3199 break;
3200
3201 case 2:
3202 add_to_list (&destructors, name);
3203 break;
3204
3205 default: /* not a constructor or destructor */
3206 continue;
3207 }
3208 }
3209
3210 if (debug)
3211 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3212 sym->si_type, sym->si_sc_type, sym->si_flags, name);
3213 }
3214 }
3215 }
3216
3217 if (symbol_load_cmds == 0)
3218 fatal ("no symbol table found");
3219
3220 /* Update the program file now, rewrite header and load commands. At present,
3221 we assume that there is enough space after the last load command to insert
3222 one more. Since the first section written out is page aligned, and the
3223 number of load commands is small, this is ok for the present. */
3224
3225 if (rw)
3226 {
3227 load_union_t *load_map;
3228 size_t size;
3229
3230 if (cmd_strings == -1)
3231 fatal ("no cmd_strings found");
3232
3233 /* Add __main to initializer list.
3001 If we are building a program instead of a shared library, don't
3234 If we are building a program instead of a shared library, do not
3002 do anything, since in the current version, you cannot do mallocs
3003 and such in the constructors. */
3004
3235 do anything, since in the current version, you cannot do mallocs
3236 and such in the constructors. */
3237
3005 if (main_sym != (symbol_info_t *)0
3238 if (main_sym != (symbol_info_t *) 0
3006 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
3007 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
3008
3009 if (debug)
3010 fprintf (stderr, "\nUpdating header and load commands.\n\n");
3011
3012 hdr.moh_n_load_cmds++;
3013 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
3014
3015 /* Create new load command map. */
3016 if (debug)
3017 fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
3018 (int)hdr.moh_n_load_cmds, (long)size);
3019
3020 load_map = (load_union_t *) xcalloc (1, size);
3021 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
3022 load_map->map.ldc_header.ldci_cmd_size = size;
3023 load_map->map.lcm_ld_cmd_strings = cmd_strings;
3024 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
3025 load_array[hdr.moh_n_load_cmds-1].load = load_map;
3026
3027 offset = hdr.moh_first_cmd_off;
3028 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3029 {
3030 load_map->map.lcm_map[i] = offset;
3031 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
3032 hdr.moh_load_map_cmd_off = offset;
3033
3034 offset += load_array[i].load->hdr.ldci_cmd_size;
3035 }
3036
3037 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
3038
3039 if (debug)
3040 print_header (&hdr);
3041
3042 /* Write header */
3043 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
3044 if (status != MO_HDR_CONV_SUCCESS)
3045 bad_header (status);
3046
3047 if (debug)
3048 fprintf (stderr, "writing load commands.\n\n");
3049
3050 /* Write load commands */
3051 offset = hdr.moh_first_cmd_off;
3052 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3053 {
3054 load_union_t *load_hdr = load_array[i].load;
3055 size_t size = load_hdr->hdr.ldci_cmd_size;
3056
3057 if (debug)
3058 print_load_command (load_hdr, offset, i);
3059
3239 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
3240 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
3241
3242 if (debug)
3243 fprintf (stderr, "\nUpdating header and load commands.\n\n");
3244
3245 hdr.moh_n_load_cmds++;
3246 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
3247
3248 /* Create new load command map. */
3249 if (debug)
3250 fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
3251 (int)hdr.moh_n_load_cmds, (long)size);
3252
3253 load_map = (load_union_t *) xcalloc (1, size);
3254 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
3255 load_map->map.ldc_header.ldci_cmd_size = size;
3256 load_map->map.lcm_ld_cmd_strings = cmd_strings;
3257 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
3258 load_array[hdr.moh_n_load_cmds-1].load = load_map;
3259
3260 offset = hdr.moh_first_cmd_off;
3261 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3262 {
3263 load_map->map.lcm_map[i] = offset;
3264 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
3265 hdr.moh_load_map_cmd_off = offset;
3266
3267 offset += load_array[i].load->hdr.ldci_cmd_size;
3268 }
3269
3270 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
3271
3272 if (debug)
3273 print_header (&hdr);
3274
3275 /* Write header */
3276 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
3277 if (status != MO_HDR_CONV_SUCCESS)
3278 bad_header (status);
3279
3280 if (debug)
3281 fprintf (stderr, "writing load commands.\n\n");
3282
3283 /* Write load commands */
3284 offset = hdr.moh_first_cmd_off;
3285 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3286 {
3287 load_union_t *load_hdr = load_array[i].load;
3288 size_t size = load_hdr->hdr.ldci_cmd_size;
3289
3290 if (debug)
3291 print_load_command (load_hdr, offset, i);
3292
3060 bcopy ((char *)load_hdr, (char *)(obj + offset), size);
3293 bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3061 offset += size;
3062 }
3063 }
3064
3065 end_file (obj_file);
3066
3067 if (close (prog_fd))
3068 fatal_perror ("closing %s", prog_name);
3069
3070 if (debug)
3071 fprintf (stderr, "\n");
3072}
3073
3074
3075/* Add a function table to the load commands to call a function
3076 on initiation or termination of the process. */
3077
3078static void
3079add_func_table (hdr_p, load_array, sym, type)
3080 mo_header_t *hdr_p; /* pointer to global header */
3081 load_all_t *load_array; /* array of ptrs to load cmds */
3082 symbol_info_t *sym; /* pointer to symbol entry */
3083 int type; /* fntc_type value */
3084{
3085 /* Add a new load command. */
3086 int num_cmds = ++hdr_p->moh_n_load_cmds;
3087 int load_index = num_cmds - 1;
3088 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3089 load_union_t *ptr = xcalloc (1, size);
3090 load_all_t *load_cmd;
3091 int i;
3092
3093 /* Set the unresolved address bit in the header to force the loader to be
3094 used, since kernel exec does not call the initialization functions. */
3095 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3096
3097 load_cmd = &load_array[load_index];
3098 load_cmd->load = ptr;
3294 offset += size;
3295 }
3296 }
3297
3298 end_file (obj_file);
3299
3300 if (close (prog_fd))
3301 fatal_perror ("closing %s", prog_name);
3302
3303 if (debug)
3304 fprintf (stderr, "\n");
3305}
3306
3307
3308/* Add a function table to the load commands to call a function
3309 on initiation or termination of the process. */
3310
3311static void
3312add_func_table (hdr_p, load_array, sym, type)
3313 mo_header_t *hdr_p; /* pointer to global header */
3314 load_all_t *load_array; /* array of ptrs to load cmds */
3315 symbol_info_t *sym; /* pointer to symbol entry */
3316 int type; /* fntc_type value */
3317{
3318 /* Add a new load command. */
3319 int num_cmds = ++hdr_p->moh_n_load_cmds;
3320 int load_index = num_cmds - 1;
3321 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3322 load_union_t *ptr = xcalloc (1, size);
3323 load_all_t *load_cmd;
3324 int i;
3325
3326 /* Set the unresolved address bit in the header to force the loader to be
3327 used, since kernel exec does not call the initialization functions. */
3328 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3329
3330 load_cmd = &load_array[load_index];
3331 load_cmd->load = ptr;
3099 load_cmd->section = (char *)0;
3332 load_cmd->section = (char *) 0;
3100
3101 /* Fill in func table load command. */
3102 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3103 ptr->func.ldc_header.ldci_cmd_size = size;
3104 ptr->func.ldc_header.ldci_section_off = 0;
3105 ptr->func.ldc_header.ldci_section_len = 0;
3106 ptr->func.fntc_type = type;
3107 ptr->func.fntc_nentries = 1;
3108
3109 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3110 /* Is the symbol already expressed as (region, offset)? */
3111 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3112 {
3113 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3114 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3115 }
3116
3117 /* If not, figure out which region it's in. */
3118 else
3119 {
3120 mo_vm_addr_t addr = sym->si_value.abs_val;
3121 int found = 0;
3122
3123 for (i = 0; i < load_index; i++)
3124 {
3125 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3126 {
3127 region_command_t *region_ptr = &load_array[i].load->region;
3128
3129 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3130 && addr >= region_ptr->regc_addr.vm_addr
3131 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3132 {
3133 ptr->func.fntc_entry_loc[0].adr_lcid = i;
3134 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3135 found++;
3136 break;
3137 }
3138 }
3139 }
3140
3141 if (!found)
3142 fatal ("could not convert 0x%l.8x into a region", addr);
3143 }
3144
3145 if (debug)
3146 fprintf (stderr,
3147 "%s function, region %d, offset = %ld (0x%.8lx)\n",
3148 (type == FNTC_INITIALIZATION) ? "init" : "term",
3149 (int)ptr->func.fntc_entry_loc[i].adr_lcid,
3150 (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
3151 (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
3152
3153}
3154
3155
3156/* Print the global header for an OSF/rose object. */
3157
3158static void
3159print_header (hdr_ptr)
3160 mo_header_t *hdr_ptr;
3161{
3162 fprintf (stderr, "\nglobal header:\n");
3163 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
3164 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
3165 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
3166 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
3167 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
3168 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
3169 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
3170 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
3171 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3172 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
3173 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3174 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3175 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3176 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3177 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
3178
3179 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3180 fprintf (stderr, ", relocatable");
3181
3182 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3183 fprintf (stderr, ", linkable");
3184
3185 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3186 fprintf (stderr, ", execable");
3187
3188 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3189 fprintf (stderr, ", executable");
3190
3191 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3192 fprintf (stderr, ", unresolved");
3193
3194 fprintf (stderr, "\n\n");
3195 return;
3196}
3197
3198
3199/* Print a short summary of a load command. */
3200
3201static void
3202print_load_command (load_hdr, offset, number)
3203 load_union_t *load_hdr;
3204 size_t offset;
3205 int number;
3206{
3207 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3333
3334 /* Fill in func table load command. */
3335 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3336 ptr->func.ldc_header.ldci_cmd_size = size;
3337 ptr->func.ldc_header.ldci_section_off = 0;
3338 ptr->func.ldc_header.ldci_section_len = 0;
3339 ptr->func.fntc_type = type;
3340 ptr->func.fntc_nentries = 1;
3341
3342 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3343 /* Is the symbol already expressed as (region, offset)? */
3344 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3345 {
3346 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3347 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3348 }
3349
3350 /* If not, figure out which region it's in. */
3351 else
3352 {
3353 mo_vm_addr_t addr = sym->si_value.abs_val;
3354 int found = 0;
3355
3356 for (i = 0; i < load_index; i++)
3357 {
3358 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3359 {
3360 region_command_t *region_ptr = &load_array[i].load->region;
3361
3362 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3363 && addr >= region_ptr->regc_addr.vm_addr
3364 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3365 {
3366 ptr->func.fntc_entry_loc[0].adr_lcid = i;
3367 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3368 found++;
3369 break;
3370 }
3371 }
3372 }
3373
3374 if (!found)
3375 fatal ("could not convert 0x%l.8x into a region", addr);
3376 }
3377
3378 if (debug)
3379 fprintf (stderr,
3380 "%s function, region %d, offset = %ld (0x%.8lx)\n",
3381 (type == FNTC_INITIALIZATION) ? "init" : "term",
3382 (int)ptr->func.fntc_entry_loc[i].adr_lcid,
3383 (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
3384 (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
3385
3386}
3387
3388
3389/* Print the global header for an OSF/rose object. */
3390
3391static void
3392print_header (hdr_ptr)
3393 mo_header_t *hdr_ptr;
3394{
3395 fprintf (stderr, "\nglobal header:\n");
3396 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
3397 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
3398 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
3399 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
3400 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
3401 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
3402 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
3403 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
3404 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3405 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
3406 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3407 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3408 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3409 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3410 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
3411
3412 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3413 fprintf (stderr, ", relocatable");
3414
3415 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3416 fprintf (stderr, ", linkable");
3417
3418 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3419 fprintf (stderr, ", execable");
3420
3421 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3422 fprintf (stderr, ", executable");
3423
3424 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3425 fprintf (stderr, ", unresolved");
3426
3427 fprintf (stderr, "\n\n");
3428 return;
3429}
3430
3431
3432/* Print a short summary of a load command. */
3433
3434static void
3435print_load_command (load_hdr, offset, number)
3436 load_union_t *load_hdr;
3437 size_t offset;
3438 int number;
3439{
3440 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3208 char *type_str = (char *)0;
3441 char *type_str = (char *) 0;
3209
3210 switch (type)
3211 {
3212 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3213 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3214 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3215 case LDC_STRINGS: type_str = "STRINGS"; break;
3216 case LDC_REGION: type_str = "REGION"; break;
3217 case LDC_RELOC: type_str = "RELOC"; break;
3218 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3219 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3220 case LDC_ENTRY: type_str = "ENTRY"; break;
3221 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3222 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3223 }
3224
3225 fprintf (stderr,
3226 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3227 number,
3228 (long) load_hdr->hdr.ldci_cmd_size,
3229 (long) offset,
3230 (long) load_hdr->hdr.ldci_section_off,
3231 (long) load_hdr->hdr.ldci_section_len);
3232
3442
3443 switch (type)
3444 {
3445 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3446 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3447 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3448 case LDC_STRINGS: type_str = "STRINGS"; break;
3449 case LDC_REGION: type_str = "REGION"; break;
3450 case LDC_RELOC: type_str = "RELOC"; break;
3451 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3452 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3453 case LDC_ENTRY: type_str = "ENTRY"; break;
3454 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3455 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3456 }
3457
3458 fprintf (stderr,
3459 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3460 number,
3461 (long) load_hdr->hdr.ldci_cmd_size,
3462 (long) offset,
3463 (long) load_hdr->hdr.ldci_section_off,
3464 (long) load_hdr->hdr.ldci_section_len);
3465
3233 if (type_str == (char *)0)
3466 if (type_str == (char *) 0)
3234 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3235
3236 else if (type != LDC_REGION)
3237 fprintf (stderr, ", ty: %s\n", type_str);
3238
3239 else
3240 {
3241 char *region = "";
3242 switch (load_hdr->region.regc_usage_type)
3243 {
3244 case REG_TEXT_T: region = ", .text"; break;
3245 case REG_DATA_T: region = ", .data"; break;
3246 case REG_BSS_T: region = ", .bss"; break;
3247 case REG_GLUE_T: region = ", .glue"; break;
3248#if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3249 case REG_RDATA_T: region = ", .rdata"; break;
3250 case REG_SDATA_T: region = ", .sdata"; break;
3251 case REG_SBSS_T: region = ", .sbss"; break;
3252#endif
3253 }
3254
3255 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3256 type_str,
3257 (long) load_hdr->region.regc_vm_addr,
3258 (long) load_hdr->region.regc_vm_size,
3259 region);
3260 }
3261
3262 return;
3263}
3264
3265
3266/* Fatal error when {en,de}code_mach_o_header fails. */
3267
3268static void
3269bad_header (status)
3270 int status;
3271{
3467 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3468
3469 else if (type != LDC_REGION)
3470 fprintf (stderr, ", ty: %s\n", type_str);
3471
3472 else
3473 {
3474 char *region = "";
3475 switch (load_hdr->region.regc_usage_type)
3476 {
3477 case REG_TEXT_T: region = ", .text"; break;
3478 case REG_DATA_T: region = ", .data"; break;
3479 case REG_BSS_T: region = ", .bss"; break;
3480 case REG_GLUE_T: region = ", .glue"; break;
3481#if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3482 case REG_RDATA_T: region = ", .rdata"; break;
3483 case REG_SDATA_T: region = ", .sdata"; break;
3484 case REG_SBSS_T: region = ", .sbss"; break;
3485#endif
3486 }
3487
3488 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3489 type_str,
3490 (long) load_hdr->region.regc_vm_addr,
3491 (long) load_hdr->region.regc_vm_size,
3492 region);
3493 }
3494
3495 return;
3496}
3497
3498
3499/* Fatal error when {en,de}code_mach_o_header fails. */
3500
3501static void
3502bad_header (status)
3503 int status;
3504{
3272 char *msg = (char *)0;
3505 char *msg = (char *) 0;
3273
3274 switch (status)
3275 {
3276 case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break;
3277 case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break;
3278 case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break;
3279 case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break;
3280 case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break;
3281 case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
3282 }
3283
3506
3507 switch (status)
3508 {
3509 case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break;
3510 case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break;
3511 case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break;
3512 case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break;
3513 case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break;
3514 case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
3515 }
3516
3284 if (msg == (char *)0)
3517 if (msg == (char *) 0)
3285 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3286 else
3287 fatal ("%s", msg);
3288}
3289
3290
3291/* Read a file into a memory buffer. */
3292
3293static struct file_info *
3294read_file (name, fd, rw)
3295 char *name; /* filename */
3296 int fd; /* file descriptor */
3297 int rw; /* read/write */
3298{
3299 struct stat stat_pkt;
3300 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3301#ifdef USE_MMAP
3302 static int page_size;
3303#endif
3304
3305 if (fstat (fd, &stat_pkt) < 0)
3306 fatal_perror ("fstat %s", name);
3307
3308 p->name = name;
3309 p->size = stat_pkt.st_size;
3310 p->rounded_size = stat_pkt.st_size;
3311 p->fd = fd;
3312 p->rw = rw;
3313
3314#ifdef USE_MMAP
3315 if (debug)
3316 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3317
3318 if (page_size == 0)
3319 page_size = sysconf (_SC_PAGE_SIZE);
3320
3321 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3518 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3519 else
3520 fatal ("%s", msg);
3521}
3522
3523
3524/* Read a file into a memory buffer. */
3525
3526static struct file_info *
3527read_file (name, fd, rw)
3528 char *name; /* filename */
3529 int fd; /* file descriptor */
3530 int rw; /* read/write */
3531{
3532 struct stat stat_pkt;
3533 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3534#ifdef USE_MMAP
3535 static int page_size;
3536#endif
3537
3538 if (fstat (fd, &stat_pkt) < 0)
3539 fatal_perror ("fstat %s", name);
3540
3541 p->name = name;
3542 p->size = stat_pkt.st_size;
3543 p->rounded_size = stat_pkt.st_size;
3544 p->fd = fd;
3545 p->rw = rw;
3546
3547#ifdef USE_MMAP
3548 if (debug)
3549 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3550
3551 if (page_size == 0)
3552 page_size = sysconf (_SC_PAGE_SIZE);
3553
3554 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3322 p->start = mmap ((caddr_t)0,
3555 p->start = mmap ((caddr_t) 0,
3323 (rw) ? p->rounded_size : p->size,
3324 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3325 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3326 fd,
3327 0L);
3328
3556 (rw) ? p->rounded_size : p->size,
3557 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3558 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3559 fd,
3560 0L);
3561
3329 if (p->start != (char *)0 && p->start != (char *)-1)
3562 if (p->start != (char *) 0 && p->start != (char *) -1)
3330 p->use_mmap = 1;
3331
3332 else
3333#endif /* USE_MMAP */
3334 {
3335 long len;
3336
3337 if (debug)
3338 fprintf (stderr, "read %s\n", name);
3339
3340 p->use_mmap = 0;
3341 p->start = xmalloc (p->size);
3342 if (lseek (fd, 0L, SEEK_SET) < 0)
3343 fatal_perror ("lseek to 0 on %s", name);
3344
3345 len = read (fd, p->start, p->size);
3346 if (len < 0)
3347 fatal_perror ("read %s", name);
3348
3349 if (len != p->size)
3350 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3351 }
3352
3353 return p;
3354}
3355
3356/* Do anything necessary to write a file back from memory. */
3357
3358static void
3359end_file (ptr)
3360 struct file_info *ptr; /* file information block */
3361{
3362#ifdef USE_MMAP
3363 if (ptr->use_mmap)
3364 {
3365 if (ptr->rw)
3366 {
3367 if (debug)
3368 fprintf (stderr, "msync %s\n", ptr->name);
3369
3370 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3371 fatal_perror ("msync %s", ptr->name);
3372 }
3373
3374 if (debug)
3375 fprintf (stderr, "munmap %s\n", ptr->name);
3376
3377 if (munmap (ptr->start, ptr->size))
3378 fatal_perror ("munmap %s", ptr->name);
3379 }
3380 else
3381#endif /* USE_MMAP */
3382 {
3383 if (ptr->rw)
3384 {
3385 long len;
3386
3387 if (debug)
3388 fprintf (stderr, "write %s\n", ptr->name);
3389
3390 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3391 fatal_perror ("lseek to 0 on %s", ptr->name);
3392
3393 len = write (ptr->fd, ptr->start, ptr->size);
3394 if (len < 0)
3395 fatal_perror ("write %s", ptr->name);
3396
3397 if (len != ptr->size)
3398 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3399 }
3400
3401 free (ptr->start);
3402 }
3403
3404 free (ptr);
3405}
3406
3407#endif /* OBJECT_FORMAT_ROSE */
3563 p->use_mmap = 1;
3564
3565 else
3566#endif /* USE_MMAP */
3567 {
3568 long len;
3569
3570 if (debug)
3571 fprintf (stderr, "read %s\n", name);
3572
3573 p->use_mmap = 0;
3574 p->start = xmalloc (p->size);
3575 if (lseek (fd, 0L, SEEK_SET) < 0)
3576 fatal_perror ("lseek to 0 on %s", name);
3577
3578 len = read (fd, p->start, p->size);
3579 if (len < 0)
3580 fatal_perror ("read %s", name);
3581
3582 if (len != p->size)
3583 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3584 }
3585
3586 return p;
3587}
3588
3589/* Do anything necessary to write a file back from memory. */
3590
3591static void
3592end_file (ptr)
3593 struct file_info *ptr; /* file information block */
3594{
3595#ifdef USE_MMAP
3596 if (ptr->use_mmap)
3597 {
3598 if (ptr->rw)
3599 {
3600 if (debug)
3601 fprintf (stderr, "msync %s\n", ptr->name);
3602
3603 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3604 fatal_perror ("msync %s", ptr->name);
3605 }
3606
3607 if (debug)
3608 fprintf (stderr, "munmap %s\n", ptr->name);
3609
3610 if (munmap (ptr->start, ptr->size))
3611 fatal_perror ("munmap %s", ptr->name);
3612 }
3613 else
3614#endif /* USE_MMAP */
3615 {
3616 if (ptr->rw)
3617 {
3618 long len;
3619
3620 if (debug)
3621 fprintf (stderr, "write %s\n", ptr->name);
3622
3623 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3624 fatal_perror ("lseek to 0 on %s", ptr->name);
3625
3626 len = write (ptr->fd, ptr->start, ptr->size);
3627 if (len < 0)
3628 fatal_perror ("write %s", ptr->name);
3629
3630 if (len != ptr->size)
3631 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3632 }
3633
3634 free (ptr->start);
3635 }
3636
3637 free (ptr);
3638}
3639
3640#endif /* OBJECT_FORMAT_ROSE */