1*e4b17023SJohn Marino /* Collect static initialization info into data structures that can be 2*e4b17023SJohn Marino traversed by C++ initialization and finalization routines. 3*e4b17023SJohn Marino Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 4*e4b17023SJohn Marino 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 5*e4b17023SJohn Marino Free Software Foundation, Inc. 6*e4b17023SJohn Marino Contributed by Chris Smith (csmith@convex.com). 7*e4b17023SJohn Marino Heavily modified by Michael Meissner (meissner@cygnus.com), 8*e4b17023SJohn Marino Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com). 9*e4b17023SJohn Marino 10*e4b17023SJohn Marino This file is part of GCC. 11*e4b17023SJohn Marino 12*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under 13*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free 14*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later 15*e4b17023SJohn Marino version. 16*e4b17023SJohn Marino 17*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY 18*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or 19*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20*e4b17023SJohn Marino for more details. 21*e4b17023SJohn Marino 22*e4b17023SJohn Marino You should have received a copy of the GNU General Public License 23*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see 24*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */ 25*e4b17023SJohn Marino 26*e4b17023SJohn Marino 27*e4b17023SJohn Marino /* Build tables of static constructors and destructors and run ld. */ 28*e4b17023SJohn Marino 29*e4b17023SJohn Marino #include "config.h" 30*e4b17023SJohn Marino #include "system.h" 31*e4b17023SJohn Marino #include "coretypes.h" 32*e4b17023SJohn Marino #include "tm.h" 33*e4b17023SJohn Marino #include "filenames.h" 34*e4b17023SJohn Marino 35*e4b17023SJohn Marino /* TARGET_64BIT may be defined to use driver specific functionality. */ 36*e4b17023SJohn Marino #undef TARGET_64BIT 37*e4b17023SJohn Marino #define TARGET_64BIT TARGET_64BIT_DEFAULT 38*e4b17023SJohn Marino 39*e4b17023SJohn Marino #ifndef LIBRARY_PATH_ENV 40*e4b17023SJohn Marino #define LIBRARY_PATH_ENV "LIBRARY_PATH" 41*e4b17023SJohn Marino #endif 42*e4b17023SJohn Marino 43*e4b17023SJohn Marino #define COLLECT 44*e4b17023SJohn Marino 45*e4b17023SJohn Marino #include "collect2.h" 46*e4b17023SJohn Marino #include "collect2-aix.h" 47*e4b17023SJohn Marino #include "diagnostic.h" 48*e4b17023SJohn Marino #include "demangle.h" 49*e4b17023SJohn Marino #include "obstack.h" 50*e4b17023SJohn Marino #include "intl.h" 51*e4b17023SJohn Marino #include "version.h" 52*e4b17023SJohn Marino 53*e4b17023SJohn Marino /* On certain systems, we have code that works by scanning the object file 54*e4b17023SJohn Marino directly. But this code uses system-specific header files and library 55*e4b17023SJohn Marino functions, so turn it off in a cross-compiler. Likewise, the names of 56*e4b17023SJohn Marino the utilities are not correct for a cross-compiler; we have to hope that 57*e4b17023SJohn Marino cross-versions are in the proper directories. */ 58*e4b17023SJohn Marino 59*e4b17023SJohn Marino #ifdef CROSS_DIRECTORY_STRUCTURE 60*e4b17023SJohn Marino #ifndef CROSS_AIX_SUPPORT 61*e4b17023SJohn Marino #undef OBJECT_FORMAT_COFF 62*e4b17023SJohn Marino #endif 63*e4b17023SJohn Marino #undef MD_EXEC_PREFIX 64*e4b17023SJohn Marino #undef REAL_LD_FILE_NAME 65*e4b17023SJohn Marino #undef REAL_NM_FILE_NAME 66*e4b17023SJohn Marino #undef REAL_STRIP_FILE_NAME 67*e4b17023SJohn Marino #endif 68*e4b17023SJohn Marino 69*e4b17023SJohn Marino /* If we cannot use a special method, use the ordinary one: 70*e4b17023SJohn Marino run nm to find what symbols are present. 71*e4b17023SJohn Marino In a cross-compiler, this means you need a cross nm, 72*e4b17023SJohn Marino but that is not quite as unpleasant as special headers. */ 73*e4b17023SJohn Marino 74*e4b17023SJohn Marino #if !defined (OBJECT_FORMAT_COFF) 75*e4b17023SJohn Marino #define OBJECT_FORMAT_NONE 76*e4b17023SJohn Marino #endif 77*e4b17023SJohn Marino 78*e4b17023SJohn Marino #ifdef OBJECT_FORMAT_COFF 79*e4b17023SJohn Marino 80*e4b17023SJohn Marino #ifndef CROSS_DIRECTORY_STRUCTURE 81*e4b17023SJohn Marino #include <a.out.h> 82*e4b17023SJohn Marino #include <ar.h> 83*e4b17023SJohn Marino 84*e4b17023SJohn Marino #ifdef UMAX 85*e4b17023SJohn Marino #include <sgs.h> 86*e4b17023SJohn Marino #endif 87*e4b17023SJohn Marino 88*e4b17023SJohn Marino /* Many versions of ldfcn.h define these. */ 89*e4b17023SJohn Marino #ifdef FREAD 90*e4b17023SJohn Marino #undef FREAD 91*e4b17023SJohn Marino #undef FWRITE 92*e4b17023SJohn Marino #endif 93*e4b17023SJohn Marino 94*e4b17023SJohn Marino #include <ldfcn.h> 95*e4b17023SJohn Marino #endif 96*e4b17023SJohn Marino 97*e4b17023SJohn Marino /* Some systems have an ISCOFF macro, but others do not. In some cases 98*e4b17023SJohn Marino the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines 99*e4b17023SJohn Marino that either do not have an ISCOFF macro in /usr/include or for those 100*e4b17023SJohn Marino where it is wrong. */ 101*e4b17023SJohn Marino 102*e4b17023SJohn Marino #ifndef MY_ISCOFF 103*e4b17023SJohn Marino #define MY_ISCOFF(X) ISCOFF (X) 104*e4b17023SJohn Marino #endif 105*e4b17023SJohn Marino 106*e4b17023SJohn Marino #endif /* OBJECT_FORMAT_COFF */ 107*e4b17023SJohn Marino 108*e4b17023SJohn Marino #ifdef OBJECT_FORMAT_NONE 109*e4b17023SJohn Marino 110*e4b17023SJohn Marino /* Default flags to pass to nm. */ 111*e4b17023SJohn Marino #ifndef NM_FLAGS 112*e4b17023SJohn Marino #define NM_FLAGS "-n" 113*e4b17023SJohn Marino #endif 114*e4b17023SJohn Marino 115*e4b17023SJohn Marino #endif /* OBJECT_FORMAT_NONE */ 116*e4b17023SJohn Marino 117*e4b17023SJohn Marino /* Some systems use __main in a way incompatible with its use in gcc, in these 118*e4b17023SJohn Marino cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to 119*e4b17023SJohn Marino give the same symbol without quotes for an alternative entry point. */ 120*e4b17023SJohn Marino #ifndef NAME__MAIN 121*e4b17023SJohn Marino #define NAME__MAIN "__main" 122*e4b17023SJohn Marino #endif 123*e4b17023SJohn Marino 124*e4b17023SJohn Marino /* This must match tree.h. */ 125*e4b17023SJohn Marino #define DEFAULT_INIT_PRIORITY 65535 126*e4b17023SJohn Marino 127*e4b17023SJohn Marino #ifndef COLLECT_SHARED_INIT_FUNC 128*e4b17023SJohn Marino #define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \ 129*e4b17023SJohn Marino fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC)) 130*e4b17023SJohn Marino #endif 131*e4b17023SJohn Marino #ifndef COLLECT_SHARED_FINI_FUNC 132*e4b17023SJohn Marino #define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \ 133*e4b17023SJohn Marino fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC)) 134*e4b17023SJohn Marino #endif 135*e4b17023SJohn Marino 136*e4b17023SJohn Marino #ifdef LDD_SUFFIX 137*e4b17023SJohn Marino #define SCAN_LIBRARIES 138*e4b17023SJohn Marino #endif 139*e4b17023SJohn Marino 140*e4b17023SJohn Marino #ifndef SHLIB_SUFFIX 141*e4b17023SJohn Marino #define SHLIB_SUFFIX ".so" 142*e4b17023SJohn Marino #endif 143*e4b17023SJohn Marino 144*e4b17023SJohn Marino #ifdef USE_COLLECT2 145*e4b17023SJohn Marino int do_collecting = 1; 146*e4b17023SJohn Marino #else 147*e4b17023SJohn Marino int do_collecting = 0; 148*e4b17023SJohn Marino #endif 149*e4b17023SJohn Marino 150*e4b17023SJohn Marino /* Cook up an always defined indication of whether we proceed the 151*e4b17023SJohn Marino "EXPORT_LIST" way. */ 152*e4b17023SJohn Marino 153*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 154*e4b17023SJohn Marino #define DO_COLLECT_EXPORT_LIST 1 155*e4b17023SJohn Marino #else 156*e4b17023SJohn Marino #define DO_COLLECT_EXPORT_LIST 0 157*e4b17023SJohn Marino #endif 158*e4b17023SJohn Marino 159*e4b17023SJohn Marino /* Nonzero if we should suppress the automatic demangling of identifiers 160*e4b17023SJohn Marino in linker error messages. Set from COLLECT_NO_DEMANGLE. */ 161*e4b17023SJohn Marino int no_demangle; 162*e4b17023SJohn Marino 163*e4b17023SJohn Marino /* Linked lists of constructor and destructor names. */ 164*e4b17023SJohn Marino 165*e4b17023SJohn Marino struct id 166*e4b17023SJohn Marino { 167*e4b17023SJohn Marino struct id *next; 168*e4b17023SJohn Marino int sequence; 169*e4b17023SJohn Marino char name[1]; 170*e4b17023SJohn Marino }; 171*e4b17023SJohn Marino 172*e4b17023SJohn Marino struct head 173*e4b17023SJohn Marino { 174*e4b17023SJohn Marino struct id *first; 175*e4b17023SJohn Marino struct id *last; 176*e4b17023SJohn Marino int number; 177*e4b17023SJohn Marino }; 178*e4b17023SJohn Marino 179*e4b17023SJohn Marino bool vflag; /* true if -v or --version */ 180*e4b17023SJohn Marino static int rflag; /* true if -r */ 181*e4b17023SJohn Marino static int strip_flag; /* true if -s */ 182*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 183*e4b17023SJohn Marino static int export_flag; /* true if -bE */ 184*e4b17023SJohn Marino static int aix64_flag; /* true if -b64 */ 185*e4b17023SJohn Marino static int aixrtl_flag; /* true if -brtl */ 186*e4b17023SJohn Marino #endif 187*e4b17023SJohn Marino 188*e4b17023SJohn Marino enum lto_mode_d { 189*e4b17023SJohn Marino LTO_MODE_NONE, /* Not doing LTO. */ 190*e4b17023SJohn Marino LTO_MODE_LTO, /* Normal LTO. */ 191*e4b17023SJohn Marino LTO_MODE_WHOPR /* WHOPR. */ 192*e4b17023SJohn Marino }; 193*e4b17023SJohn Marino 194*e4b17023SJohn Marino /* Current LTO mode. */ 195*e4b17023SJohn Marino static enum lto_mode_d lto_mode = LTO_MODE_NONE; 196*e4b17023SJohn Marino 197*e4b17023SJohn Marino bool debug; /* true if -debug */ 198*e4b17023SJohn Marino bool helpflag; /* true if --help */ 199*e4b17023SJohn Marino 200*e4b17023SJohn Marino static int shared_obj; /* true if -shared */ 201*e4b17023SJohn Marino 202*e4b17023SJohn Marino static const char *c_file; /* <xxx>.c for constructor/destructor list. */ 203*e4b17023SJohn Marino static const char *o_file; /* <xxx>.o for constructor/destructor list. */ 204*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 205*e4b17023SJohn Marino static const char *export_file; /* <xxx>.x for AIX export list. */ 206*e4b17023SJohn Marino #endif 207*e4b17023SJohn Marino static char **lto_o_files; /* Output files for LTO. */ 208*e4b17023SJohn Marino const char *ldout; /* File for ld stdout. */ 209*e4b17023SJohn Marino const char *lderrout; /* File for ld stderr. */ 210*e4b17023SJohn Marino static const char *output_file; /* Output file for ld. */ 211*e4b17023SJohn Marino static const char *nm_file_name; /* pathname of nm */ 212*e4b17023SJohn Marino #ifdef LDD_SUFFIX 213*e4b17023SJohn Marino static const char *ldd_file_name; /* pathname of ldd (or equivalent) */ 214*e4b17023SJohn Marino #endif 215*e4b17023SJohn Marino static const char *strip_file_name; /* pathname of strip */ 216*e4b17023SJohn Marino const char *c_file_name; /* pathname of gcc */ 217*e4b17023SJohn Marino static char *initname, *fininame; /* names of init and fini funcs */ 218*e4b17023SJohn Marino 219*e4b17023SJohn Marino static struct head constructors; /* list of constructors found */ 220*e4b17023SJohn Marino static struct head destructors; /* list of destructors found */ 221*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 222*e4b17023SJohn Marino static struct head exports; /* list of exported symbols */ 223*e4b17023SJohn Marino #endif 224*e4b17023SJohn Marino static struct head frame_tables; /* list of frame unwind info tables */ 225*e4b17023SJohn Marino 226*e4b17023SJohn Marino static bool at_file_supplied; /* Whether to use @file arguments */ 227*e4b17023SJohn Marino static char *response_file; /* Name of any current response file */ 228*e4b17023SJohn Marino 229*e4b17023SJohn Marino struct obstack temporary_obstack; 230*e4b17023SJohn Marino char * temporary_firstobj; 231*e4b17023SJohn Marino 232*e4b17023SJohn Marino /* A string that must be prepended to a target OS path in order to find 233*e4b17023SJohn Marino it on the host system. */ 234*e4b17023SJohn Marino #ifdef TARGET_SYSTEM_ROOT 235*e4b17023SJohn Marino static const char *target_system_root = TARGET_SYSTEM_ROOT; 236*e4b17023SJohn Marino #else 237*e4b17023SJohn Marino static const char *target_system_root = ""; 238*e4b17023SJohn Marino #endif 239*e4b17023SJohn Marino 240*e4b17023SJohn Marino /* Structure to hold all the directories in which to search for files to 241*e4b17023SJohn Marino execute. */ 242*e4b17023SJohn Marino 243*e4b17023SJohn Marino struct prefix_list 244*e4b17023SJohn Marino { 245*e4b17023SJohn Marino const char *prefix; /* String to prepend to the path. */ 246*e4b17023SJohn Marino struct prefix_list *next; /* Next in linked list. */ 247*e4b17023SJohn Marino }; 248*e4b17023SJohn Marino 249*e4b17023SJohn Marino struct path_prefix 250*e4b17023SJohn Marino { 251*e4b17023SJohn Marino struct prefix_list *plist; /* List of prefixes to try */ 252*e4b17023SJohn Marino int max_len; /* Max length of a prefix in PLIST */ 253*e4b17023SJohn Marino const char *name; /* Name of this list (used in config stuff) */ 254*e4b17023SJohn Marino }; 255*e4b17023SJohn Marino 256*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 257*e4b17023SJohn Marino /* Lists to keep libraries to be scanned for global constructors/destructors. */ 258*e4b17023SJohn Marino static struct head libs; /* list of libraries */ 259*e4b17023SJohn Marino static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */ 260*e4b17023SJohn Marino static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */ 261*e4b17023SJohn Marino static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs, 262*e4b17023SJohn Marino &libpath_lib_dirs, NULL}; 263*e4b17023SJohn Marino #endif 264*e4b17023SJohn Marino 265*e4b17023SJohn Marino /* List of names of object files containing LTO information. 266*e4b17023SJohn Marino These are a subset of the object file names appearing on the 267*e4b17023SJohn Marino command line, and must be identical, in the sense of pointer 268*e4b17023SJohn Marino equality, with the names passed to maybe_run_lto_and_relink(). */ 269*e4b17023SJohn Marino 270*e4b17023SJohn Marino struct lto_object 271*e4b17023SJohn Marino { 272*e4b17023SJohn Marino const char *name; /* Name of object file. */ 273*e4b17023SJohn Marino struct lto_object *next; /* Next in linked list. */ 274*e4b17023SJohn Marino }; 275*e4b17023SJohn Marino 276*e4b17023SJohn Marino struct lto_object_list 277*e4b17023SJohn Marino { 278*e4b17023SJohn Marino struct lto_object *first; /* First list element. */ 279*e4b17023SJohn Marino struct lto_object *last; /* Last list element. */ 280*e4b17023SJohn Marino }; 281*e4b17023SJohn Marino 282*e4b17023SJohn Marino static struct lto_object_list lto_objects; 283*e4b17023SJohn Marino 284*e4b17023SJohn Marino /* Special kinds of symbols that a name may denote. */ 285*e4b17023SJohn Marino 286*e4b17023SJohn Marino typedef enum { 287*e4b17023SJohn Marino SYM_REGULAR = 0, /* nothing special */ 288*e4b17023SJohn Marino 289*e4b17023SJohn Marino SYM_CTOR = 1, /* constructor */ 290*e4b17023SJohn Marino SYM_DTOR = 2, /* destructor */ 291*e4b17023SJohn Marino SYM_INIT = 3, /* shared object routine that calls all the ctors */ 292*e4b17023SJohn Marino SYM_FINI = 4, /* shared object routine that calls all the dtors */ 293*e4b17023SJohn Marino SYM_DWEH = 5 /* DWARF exception handling table */ 294*e4b17023SJohn Marino } symkind; 295*e4b17023SJohn Marino 296*e4b17023SJohn Marino static symkind is_ctor_dtor (const char *); 297*e4b17023SJohn Marino 298*e4b17023SJohn Marino static void handler (int); 299*e4b17023SJohn Marino static char *find_a_file (struct path_prefix *, const char *); 300*e4b17023SJohn Marino static void add_prefix (struct path_prefix *, const char *); 301*e4b17023SJohn Marino static void prefix_from_env (const char *, struct path_prefix *); 302*e4b17023SJohn Marino static void prefix_from_string (const char *, struct path_prefix *); 303*e4b17023SJohn Marino static void do_wait (const char *, struct pex_obj *); 304*e4b17023SJohn Marino static void fork_execute (const char *, char **); 305*e4b17023SJohn Marino static void maybe_unlink (const char *); 306*e4b17023SJohn Marino static void maybe_unlink_list (char **); 307*e4b17023SJohn Marino static void add_to_list (struct head *, const char *); 308*e4b17023SJohn Marino static int extract_init_priority (const char *); 309*e4b17023SJohn Marino static void sort_ids (struct head *); 310*e4b17023SJohn Marino static void write_list (FILE *, const char *, struct id *); 311*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 312*e4b17023SJohn Marino static void dump_list (FILE *, const char *, struct id *); 313*e4b17023SJohn Marino #endif 314*e4b17023SJohn Marino #if 0 315*e4b17023SJohn Marino static void dump_prefix_list (FILE *, const char *, struct prefix_list *); 316*e4b17023SJohn Marino #endif 317*e4b17023SJohn Marino static void write_list_with_asm (FILE *, const char *, struct id *); 318*e4b17023SJohn Marino static void write_c_file (FILE *, const char *); 319*e4b17023SJohn Marino static void write_c_file_stat (FILE *, const char *); 320*e4b17023SJohn Marino #ifndef LD_INIT_SWITCH 321*e4b17023SJohn Marino static void write_c_file_glob (FILE *, const char *); 322*e4b17023SJohn Marino #endif 323*e4b17023SJohn Marino #ifdef SCAN_LIBRARIES 324*e4b17023SJohn Marino static void scan_libraries (const char *); 325*e4b17023SJohn Marino #endif 326*e4b17023SJohn Marino #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES 327*e4b17023SJohn Marino static int is_in_args (const char *, const char **, const char **); 328*e4b17023SJohn Marino #endif 329*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 330*e4b17023SJohn Marino #if 0 331*e4b17023SJohn Marino static int is_in_list (const char *, struct id *); 332*e4b17023SJohn Marino #endif 333*e4b17023SJohn Marino static void write_aix_file (FILE *, struct id *); 334*e4b17023SJohn Marino static char *resolve_lib_name (const char *); 335*e4b17023SJohn Marino #endif 336*e4b17023SJohn Marino static char *extract_string (const char **); 337*e4b17023SJohn Marino static void post_ld_pass (bool); 338*e4b17023SJohn Marino static void process_args (int *argcp, char **argv); 339*e4b17023SJohn Marino 340*e4b17023SJohn Marino /* Enumerations describing which pass this is for scanning the 341*e4b17023SJohn Marino program file ... */ 342*e4b17023SJohn Marino 343*e4b17023SJohn Marino typedef enum { 344*e4b17023SJohn Marino PASS_FIRST, /* without constructors */ 345*e4b17023SJohn Marino PASS_OBJ, /* individual objects */ 346*e4b17023SJohn Marino PASS_LIB, /* looking for shared libraries */ 347*e4b17023SJohn Marino PASS_SECOND, /* with constructors linked in */ 348*e4b17023SJohn Marino PASS_LTOINFO /* looking for objects with LTO info */ 349*e4b17023SJohn Marino } scanpass; 350*e4b17023SJohn Marino 351*e4b17023SJohn Marino /* ... and which kinds of symbols are to be considered. */ 352*e4b17023SJohn Marino 353*e4b17023SJohn Marino enum scanfilter_masks { 354*e4b17023SJohn Marino SCAN_NOTHING = 0, 355*e4b17023SJohn Marino 356*e4b17023SJohn Marino SCAN_CTOR = 1 << SYM_CTOR, 357*e4b17023SJohn Marino SCAN_DTOR = 1 << SYM_DTOR, 358*e4b17023SJohn Marino SCAN_INIT = 1 << SYM_INIT, 359*e4b17023SJohn Marino SCAN_FINI = 1 << SYM_FINI, 360*e4b17023SJohn Marino SCAN_DWEH = 1 << SYM_DWEH, 361*e4b17023SJohn Marino SCAN_ALL = ~0 362*e4b17023SJohn Marino }; 363*e4b17023SJohn Marino 364*e4b17023SJohn Marino /* This type is used for parameters and variables which hold 365*e4b17023SJohn Marino combinations of the flags in enum scanfilter_masks. */ 366*e4b17023SJohn Marino typedef int scanfilter; 367*e4b17023SJohn Marino 368*e4b17023SJohn Marino /* Scan the name list of the loaded program for the symbols g++ uses for 369*e4b17023SJohn Marino static constructors and destructors. 370*e4b17023SJohn Marino 371*e4b17023SJohn Marino The SCANPASS argument tells which collect processing pass this is for and 372*e4b17023SJohn Marino the SCANFILTER argument tells which kinds of symbols to consider in this 373*e4b17023SJohn Marino pass. Symbols of a special kind not in the filter mask are considered as 374*e4b17023SJohn Marino regular ones. 375*e4b17023SJohn Marino 376*e4b17023SJohn Marino The constructor table begins at __CTOR_LIST__ and contains a count of the 377*e4b17023SJohn Marino number of pointers (or -1 if the constructors are built in a separate 378*e4b17023SJohn Marino section by the linker), followed by the pointers to the constructor 379*e4b17023SJohn Marino functions, terminated with a null pointer. The destructor table has the 380*e4b17023SJohn Marino same format, and begins at __DTOR_LIST__. */ 381*e4b17023SJohn Marino 382*e4b17023SJohn Marino static void scan_prog_file (const char *, scanpass, scanfilter); 383*e4b17023SJohn Marino 384*e4b17023SJohn Marino 385*e4b17023SJohn Marino /* Delete tempfiles and exit function. */ 386*e4b17023SJohn Marino 387*e4b17023SJohn Marino void 388*e4b17023SJohn Marino collect_exit (int status) 389*e4b17023SJohn Marino { 390*e4b17023SJohn Marino if (c_file != 0 && c_file[0]) 391*e4b17023SJohn Marino maybe_unlink (c_file); 392*e4b17023SJohn Marino 393*e4b17023SJohn Marino if (o_file != 0 && o_file[0]) 394*e4b17023SJohn Marino maybe_unlink (o_file); 395*e4b17023SJohn Marino 396*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 397*e4b17023SJohn Marino if (export_file != 0 && export_file[0]) 398*e4b17023SJohn Marino maybe_unlink (export_file); 399*e4b17023SJohn Marino #endif 400*e4b17023SJohn Marino 401*e4b17023SJohn Marino if (lto_o_files) 402*e4b17023SJohn Marino maybe_unlink_list (lto_o_files); 403*e4b17023SJohn Marino 404*e4b17023SJohn Marino if (ldout != 0 && ldout[0]) 405*e4b17023SJohn Marino { 406*e4b17023SJohn Marino dump_file (ldout, stdout); 407*e4b17023SJohn Marino maybe_unlink (ldout); 408*e4b17023SJohn Marino } 409*e4b17023SJohn Marino 410*e4b17023SJohn Marino if (lderrout != 0 && lderrout[0]) 411*e4b17023SJohn Marino { 412*e4b17023SJohn Marino dump_file (lderrout, stderr); 413*e4b17023SJohn Marino maybe_unlink (lderrout); 414*e4b17023SJohn Marino } 415*e4b17023SJohn Marino 416*e4b17023SJohn Marino if (status != 0 && output_file != 0 && output_file[0]) 417*e4b17023SJohn Marino maybe_unlink (output_file); 418*e4b17023SJohn Marino 419*e4b17023SJohn Marino if (response_file) 420*e4b17023SJohn Marino maybe_unlink (response_file); 421*e4b17023SJohn Marino 422*e4b17023SJohn Marino exit (status); 423*e4b17023SJohn Marino } 424*e4b17023SJohn Marino 425*e4b17023SJohn Marino 426*e4b17023SJohn Marino /* Notify user of a non-error. */ 427*e4b17023SJohn Marino void 428*e4b17023SJohn Marino notice (const char *cmsgid, ...) 429*e4b17023SJohn Marino { 430*e4b17023SJohn Marino va_list ap; 431*e4b17023SJohn Marino 432*e4b17023SJohn Marino va_start (ap, cmsgid); 433*e4b17023SJohn Marino vfprintf (stderr, _(cmsgid), ap); 434*e4b17023SJohn Marino va_end (ap); 435*e4b17023SJohn Marino } 436*e4b17023SJohn Marino 437*e4b17023SJohn Marino /* Notify user of a non-error, without translating the format string. */ 438*e4b17023SJohn Marino void 439*e4b17023SJohn Marino notice_translated (const char *cmsgid, ...) 440*e4b17023SJohn Marino { 441*e4b17023SJohn Marino va_list ap; 442*e4b17023SJohn Marino 443*e4b17023SJohn Marino va_start (ap, cmsgid); 444*e4b17023SJohn Marino vfprintf (stderr, cmsgid, ap); 445*e4b17023SJohn Marino va_end (ap); 446*e4b17023SJohn Marino } 447*e4b17023SJohn Marino 448*e4b17023SJohn Marino static void 449*e4b17023SJohn Marino handler (int signo) 450*e4b17023SJohn Marino { 451*e4b17023SJohn Marino if (c_file != 0 && c_file[0]) 452*e4b17023SJohn Marino maybe_unlink (c_file); 453*e4b17023SJohn Marino 454*e4b17023SJohn Marino if (o_file != 0 && o_file[0]) 455*e4b17023SJohn Marino maybe_unlink (o_file); 456*e4b17023SJohn Marino 457*e4b17023SJohn Marino if (ldout != 0 && ldout[0]) 458*e4b17023SJohn Marino maybe_unlink (ldout); 459*e4b17023SJohn Marino 460*e4b17023SJohn Marino if (lderrout != 0 && lderrout[0]) 461*e4b17023SJohn Marino maybe_unlink (lderrout); 462*e4b17023SJohn Marino 463*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 464*e4b17023SJohn Marino if (export_file != 0 && export_file[0]) 465*e4b17023SJohn Marino maybe_unlink (export_file); 466*e4b17023SJohn Marino #endif 467*e4b17023SJohn Marino 468*e4b17023SJohn Marino if (lto_o_files) 469*e4b17023SJohn Marino maybe_unlink_list (lto_o_files); 470*e4b17023SJohn Marino 471*e4b17023SJohn Marino if (response_file) 472*e4b17023SJohn Marino maybe_unlink (response_file); 473*e4b17023SJohn Marino 474*e4b17023SJohn Marino signal (signo, SIG_DFL); 475*e4b17023SJohn Marino raise (signo); 476*e4b17023SJohn Marino } 477*e4b17023SJohn Marino 478*e4b17023SJohn Marino 479*e4b17023SJohn Marino int 480*e4b17023SJohn Marino file_exists (const char *name) 481*e4b17023SJohn Marino { 482*e4b17023SJohn Marino return access (name, R_OK) == 0; 483*e4b17023SJohn Marino } 484*e4b17023SJohn Marino 485*e4b17023SJohn Marino /* Parse a reasonable subset of shell quoting syntax. */ 486*e4b17023SJohn Marino 487*e4b17023SJohn Marino static char * 488*e4b17023SJohn Marino extract_string (const char **pp) 489*e4b17023SJohn Marino { 490*e4b17023SJohn Marino const char *p = *pp; 491*e4b17023SJohn Marino int backquote = 0; 492*e4b17023SJohn Marino int inside = 0; 493*e4b17023SJohn Marino 494*e4b17023SJohn Marino for (;;) 495*e4b17023SJohn Marino { 496*e4b17023SJohn Marino char c = *p; 497*e4b17023SJohn Marino if (c == '\0') 498*e4b17023SJohn Marino break; 499*e4b17023SJohn Marino ++p; 500*e4b17023SJohn Marino if (backquote) 501*e4b17023SJohn Marino obstack_1grow (&temporary_obstack, c); 502*e4b17023SJohn Marino else if (! inside && c == ' ') 503*e4b17023SJohn Marino break; 504*e4b17023SJohn Marino else if (! inside && c == '\\') 505*e4b17023SJohn Marino backquote = 1; 506*e4b17023SJohn Marino else if (c == '\'') 507*e4b17023SJohn Marino inside = !inside; 508*e4b17023SJohn Marino else 509*e4b17023SJohn Marino obstack_1grow (&temporary_obstack, c); 510*e4b17023SJohn Marino } 511*e4b17023SJohn Marino 512*e4b17023SJohn Marino obstack_1grow (&temporary_obstack, '\0'); 513*e4b17023SJohn Marino *pp = p; 514*e4b17023SJohn Marino return XOBFINISH (&temporary_obstack, char *); 515*e4b17023SJohn Marino } 516*e4b17023SJohn Marino 517*e4b17023SJohn Marino void 518*e4b17023SJohn Marino dump_file (const char *name, FILE *to) 519*e4b17023SJohn Marino { 520*e4b17023SJohn Marino FILE *stream = fopen (name, "r"); 521*e4b17023SJohn Marino 522*e4b17023SJohn Marino if (stream == 0) 523*e4b17023SJohn Marino return; 524*e4b17023SJohn Marino while (1) 525*e4b17023SJohn Marino { 526*e4b17023SJohn Marino int c; 527*e4b17023SJohn Marino while (c = getc (stream), 528*e4b17023SJohn Marino c != EOF && (ISIDNUM (c) || c == '$' || c == '.')) 529*e4b17023SJohn Marino obstack_1grow (&temporary_obstack, c); 530*e4b17023SJohn Marino if (obstack_object_size (&temporary_obstack) > 0) 531*e4b17023SJohn Marino { 532*e4b17023SJohn Marino const char *word, *p; 533*e4b17023SJohn Marino char *result; 534*e4b17023SJohn Marino obstack_1grow (&temporary_obstack, '\0'); 535*e4b17023SJohn Marino word = XOBFINISH (&temporary_obstack, const char *); 536*e4b17023SJohn Marino 537*e4b17023SJohn Marino if (*word == '.') 538*e4b17023SJohn Marino ++word, putc ('.', to); 539*e4b17023SJohn Marino p = word; 540*e4b17023SJohn Marino if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX))) 541*e4b17023SJohn Marino p += strlen (USER_LABEL_PREFIX); 542*e4b17023SJohn Marino 543*e4b17023SJohn Marino #ifdef HAVE_LD_DEMANGLE 544*e4b17023SJohn Marino result = 0; 545*e4b17023SJohn Marino #else 546*e4b17023SJohn Marino if (no_demangle) 547*e4b17023SJohn Marino result = 0; 548*e4b17023SJohn Marino else 549*e4b17023SJohn Marino result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE); 550*e4b17023SJohn Marino #endif 551*e4b17023SJohn Marino 552*e4b17023SJohn Marino if (result) 553*e4b17023SJohn Marino { 554*e4b17023SJohn Marino int diff; 555*e4b17023SJohn Marino fputs (result, to); 556*e4b17023SJohn Marino 557*e4b17023SJohn Marino diff = strlen (word) - strlen (result); 558*e4b17023SJohn Marino while (diff > 0 && c == ' ') 559*e4b17023SJohn Marino --diff, putc (' ', to); 560*e4b17023SJohn Marino if (diff < 0 && c == ' ') 561*e4b17023SJohn Marino { 562*e4b17023SJohn Marino while (diff < 0 && c == ' ') 563*e4b17023SJohn Marino ++diff, c = getc (stream); 564*e4b17023SJohn Marino if (!ISSPACE (c)) 565*e4b17023SJohn Marino { 566*e4b17023SJohn Marino /* Make sure we output at least one space, or 567*e4b17023SJohn Marino the demangled symbol name will run into 568*e4b17023SJohn Marino whatever text follows. */ 569*e4b17023SJohn Marino putc (' ', to); 570*e4b17023SJohn Marino } 571*e4b17023SJohn Marino } 572*e4b17023SJohn Marino 573*e4b17023SJohn Marino free (result); 574*e4b17023SJohn Marino } 575*e4b17023SJohn Marino else 576*e4b17023SJohn Marino fputs (word, to); 577*e4b17023SJohn Marino 578*e4b17023SJohn Marino fflush (to); 579*e4b17023SJohn Marino obstack_free (&temporary_obstack, temporary_firstobj); 580*e4b17023SJohn Marino } 581*e4b17023SJohn Marino if (c == EOF) 582*e4b17023SJohn Marino break; 583*e4b17023SJohn Marino putc (c, to); 584*e4b17023SJohn Marino } 585*e4b17023SJohn Marino fclose (stream); 586*e4b17023SJohn Marino } 587*e4b17023SJohn Marino 588*e4b17023SJohn Marino /* Return the kind of symbol denoted by name S. */ 589*e4b17023SJohn Marino 590*e4b17023SJohn Marino static symkind 591*e4b17023SJohn Marino is_ctor_dtor (const char *s) 592*e4b17023SJohn Marino { 593*e4b17023SJohn Marino struct names { const char *const name; const int len; symkind ret; 594*e4b17023SJohn Marino const int two_underscores; }; 595*e4b17023SJohn Marino 596*e4b17023SJohn Marino const struct names *p; 597*e4b17023SJohn Marino int ch; 598*e4b17023SJohn Marino const char *orig_s = s; 599*e4b17023SJohn Marino 600*e4b17023SJohn Marino static const struct names special[] = { 601*e4b17023SJohn Marino #ifndef NO_DOLLAR_IN_LABEL 602*e4b17023SJohn Marino { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, SYM_CTOR, 0 }, 603*e4b17023SJohn Marino { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, SYM_DTOR, 0 }, 604*e4b17023SJohn Marino #else 605*e4b17023SJohn Marino #ifndef NO_DOT_IN_LABEL 606*e4b17023SJohn Marino { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, SYM_CTOR, 0 }, 607*e4b17023SJohn Marino { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, SYM_DTOR, 0 }, 608*e4b17023SJohn Marino #endif /* NO_DOT_IN_LABEL */ 609*e4b17023SJohn Marino #endif /* NO_DOLLAR_IN_LABEL */ 610*e4b17023SJohn Marino { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, SYM_CTOR, 0 }, 611*e4b17023SJohn Marino { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, SYM_DTOR, 0 }, 612*e4b17023SJohn Marino { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, SYM_DWEH, 0 }, 613*e4b17023SJohn Marino { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, SYM_INIT, 0 }, 614*e4b17023SJohn Marino { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, SYM_FINI, 0 }, 615*e4b17023SJohn Marino { NULL, 0, SYM_REGULAR, 0 } 616*e4b17023SJohn Marino }; 617*e4b17023SJohn Marino 618*e4b17023SJohn Marino while ((ch = *s) == '_') 619*e4b17023SJohn Marino ++s; 620*e4b17023SJohn Marino 621*e4b17023SJohn Marino if (s == orig_s) 622*e4b17023SJohn Marino return SYM_REGULAR; 623*e4b17023SJohn Marino 624*e4b17023SJohn Marino for (p = &special[0]; p->len > 0; p++) 625*e4b17023SJohn Marino { 626*e4b17023SJohn Marino if (ch == p->name[0] 627*e4b17023SJohn Marino && (!p->two_underscores || ((s - orig_s) >= 2)) 628*e4b17023SJohn Marino && strncmp(s, p->name, p->len) == 0) 629*e4b17023SJohn Marino { 630*e4b17023SJohn Marino return p->ret; 631*e4b17023SJohn Marino } 632*e4b17023SJohn Marino } 633*e4b17023SJohn Marino return SYM_REGULAR; 634*e4b17023SJohn Marino } 635*e4b17023SJohn Marino 636*e4b17023SJohn Marino /* We maintain two prefix lists: one from COMPILER_PATH environment variable 637*e4b17023SJohn Marino and one from the PATH variable. */ 638*e4b17023SJohn Marino 639*e4b17023SJohn Marino static struct path_prefix cpath, path; 640*e4b17023SJohn Marino 641*e4b17023SJohn Marino #ifdef CROSS_DIRECTORY_STRUCTURE 642*e4b17023SJohn Marino /* This is the name of the target machine. We use it to form the name 643*e4b17023SJohn Marino of the files to execute. */ 644*e4b17023SJohn Marino 645*e4b17023SJohn Marino static const char *const target_machine = TARGET_MACHINE; 646*e4b17023SJohn Marino #endif 647*e4b17023SJohn Marino 648*e4b17023SJohn Marino /* Search for NAME using prefix list PPREFIX. We only look for executable 649*e4b17023SJohn Marino files. 650*e4b17023SJohn Marino 651*e4b17023SJohn Marino Return 0 if not found, otherwise return its name, allocated with malloc. */ 652*e4b17023SJohn Marino 653*e4b17023SJohn Marino static char * 654*e4b17023SJohn Marino find_a_file (struct path_prefix *pprefix, const char *name) 655*e4b17023SJohn Marino { 656*e4b17023SJohn Marino char *temp; 657*e4b17023SJohn Marino struct prefix_list *pl; 658*e4b17023SJohn Marino int len = pprefix->max_len + strlen (name) + 1; 659*e4b17023SJohn Marino 660*e4b17023SJohn Marino if (debug) 661*e4b17023SJohn Marino fprintf (stderr, "Looking for '%s'\n", name); 662*e4b17023SJohn Marino 663*e4b17023SJohn Marino #ifdef HOST_EXECUTABLE_SUFFIX 664*e4b17023SJohn Marino len += strlen (HOST_EXECUTABLE_SUFFIX); 665*e4b17023SJohn Marino #endif 666*e4b17023SJohn Marino 667*e4b17023SJohn Marino temp = XNEWVEC (char, len); 668*e4b17023SJohn Marino 669*e4b17023SJohn Marino /* Determine the filename to execute (special case for absolute paths). */ 670*e4b17023SJohn Marino 671*e4b17023SJohn Marino if (IS_ABSOLUTE_PATH (name)) 672*e4b17023SJohn Marino { 673*e4b17023SJohn Marino if (access (name, X_OK) == 0) 674*e4b17023SJohn Marino { 675*e4b17023SJohn Marino strcpy (temp, name); 676*e4b17023SJohn Marino 677*e4b17023SJohn Marino if (debug) 678*e4b17023SJohn Marino fprintf (stderr, " - found: absolute path\n"); 679*e4b17023SJohn Marino 680*e4b17023SJohn Marino return temp; 681*e4b17023SJohn Marino } 682*e4b17023SJohn Marino 683*e4b17023SJohn Marino #ifdef HOST_EXECUTABLE_SUFFIX 684*e4b17023SJohn Marino /* Some systems have a suffix for executable files. 685*e4b17023SJohn Marino So try appending that. */ 686*e4b17023SJohn Marino strcpy (temp, name); 687*e4b17023SJohn Marino strcat (temp, HOST_EXECUTABLE_SUFFIX); 688*e4b17023SJohn Marino 689*e4b17023SJohn Marino if (access (temp, X_OK) == 0) 690*e4b17023SJohn Marino return temp; 691*e4b17023SJohn Marino #endif 692*e4b17023SJohn Marino 693*e4b17023SJohn Marino if (debug) 694*e4b17023SJohn Marino fprintf (stderr, " - failed to locate using absolute path\n"); 695*e4b17023SJohn Marino } 696*e4b17023SJohn Marino else 697*e4b17023SJohn Marino for (pl = pprefix->plist; pl; pl = pl->next) 698*e4b17023SJohn Marino { 699*e4b17023SJohn Marino struct stat st; 700*e4b17023SJohn Marino 701*e4b17023SJohn Marino strcpy (temp, pl->prefix); 702*e4b17023SJohn Marino strcat (temp, name); 703*e4b17023SJohn Marino 704*e4b17023SJohn Marino if (stat (temp, &st) >= 0 705*e4b17023SJohn Marino && ! S_ISDIR (st.st_mode) 706*e4b17023SJohn Marino && access (temp, X_OK) == 0) 707*e4b17023SJohn Marino return temp; 708*e4b17023SJohn Marino 709*e4b17023SJohn Marino #ifdef HOST_EXECUTABLE_SUFFIX 710*e4b17023SJohn Marino /* Some systems have a suffix for executable files. 711*e4b17023SJohn Marino So try appending that. */ 712*e4b17023SJohn Marino strcat (temp, HOST_EXECUTABLE_SUFFIX); 713*e4b17023SJohn Marino 714*e4b17023SJohn Marino if (stat (temp, &st) >= 0 715*e4b17023SJohn Marino && ! S_ISDIR (st.st_mode) 716*e4b17023SJohn Marino && access (temp, X_OK) == 0) 717*e4b17023SJohn Marino return temp; 718*e4b17023SJohn Marino #endif 719*e4b17023SJohn Marino } 720*e4b17023SJohn Marino 721*e4b17023SJohn Marino if (debug && pprefix->plist == NULL) 722*e4b17023SJohn Marino fprintf (stderr, " - failed: no entries in prefix list\n"); 723*e4b17023SJohn Marino 724*e4b17023SJohn Marino free (temp); 725*e4b17023SJohn Marino return 0; 726*e4b17023SJohn Marino } 727*e4b17023SJohn Marino 728*e4b17023SJohn Marino /* Add an entry for PREFIX to prefix list PPREFIX. */ 729*e4b17023SJohn Marino 730*e4b17023SJohn Marino static void 731*e4b17023SJohn Marino add_prefix (struct path_prefix *pprefix, const char *prefix) 732*e4b17023SJohn Marino { 733*e4b17023SJohn Marino struct prefix_list *pl, **prev; 734*e4b17023SJohn Marino int len; 735*e4b17023SJohn Marino 736*e4b17023SJohn Marino if (pprefix->plist) 737*e4b17023SJohn Marino { 738*e4b17023SJohn Marino for (pl = pprefix->plist; pl->next; pl = pl->next) 739*e4b17023SJohn Marino ; 740*e4b17023SJohn Marino prev = &pl->next; 741*e4b17023SJohn Marino } 742*e4b17023SJohn Marino else 743*e4b17023SJohn Marino prev = &pprefix->plist; 744*e4b17023SJohn Marino 745*e4b17023SJohn Marino /* Keep track of the longest prefix. */ 746*e4b17023SJohn Marino 747*e4b17023SJohn Marino len = strlen (prefix); 748*e4b17023SJohn Marino if (len > pprefix->max_len) 749*e4b17023SJohn Marino pprefix->max_len = len; 750*e4b17023SJohn Marino 751*e4b17023SJohn Marino pl = XNEW (struct prefix_list); 752*e4b17023SJohn Marino pl->prefix = xstrdup (prefix); 753*e4b17023SJohn Marino 754*e4b17023SJohn Marino if (*prev) 755*e4b17023SJohn Marino pl->next = *prev; 756*e4b17023SJohn Marino else 757*e4b17023SJohn Marino pl->next = (struct prefix_list *) 0; 758*e4b17023SJohn Marino *prev = pl; 759*e4b17023SJohn Marino } 760*e4b17023SJohn Marino 761*e4b17023SJohn Marino /* Take the value of the environment variable ENV, break it into a path, and 762*e4b17023SJohn Marino add of the entries to PPREFIX. */ 763*e4b17023SJohn Marino 764*e4b17023SJohn Marino static void 765*e4b17023SJohn Marino prefix_from_env (const char *env, struct path_prefix *pprefix) 766*e4b17023SJohn Marino { 767*e4b17023SJohn Marino const char *p; 768*e4b17023SJohn Marino p = getenv (env); 769*e4b17023SJohn Marino 770*e4b17023SJohn Marino if (p) 771*e4b17023SJohn Marino prefix_from_string (p, pprefix); 772*e4b17023SJohn Marino } 773*e4b17023SJohn Marino 774*e4b17023SJohn Marino static void 775*e4b17023SJohn Marino prefix_from_string (const char *p, struct path_prefix *pprefix) 776*e4b17023SJohn Marino { 777*e4b17023SJohn Marino const char *startp, *endp; 778*e4b17023SJohn Marino char *nstore = XNEWVEC (char, strlen (p) + 3); 779*e4b17023SJohn Marino 780*e4b17023SJohn Marino if (debug) 781*e4b17023SJohn Marino fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR); 782*e4b17023SJohn Marino 783*e4b17023SJohn Marino startp = endp = p; 784*e4b17023SJohn Marino while (1) 785*e4b17023SJohn Marino { 786*e4b17023SJohn Marino if (*endp == PATH_SEPARATOR || *endp == 0) 787*e4b17023SJohn Marino { 788*e4b17023SJohn Marino strncpy (nstore, startp, endp-startp); 789*e4b17023SJohn Marino if (endp == startp) 790*e4b17023SJohn Marino { 791*e4b17023SJohn Marino strcpy (nstore, "./"); 792*e4b17023SJohn Marino } 793*e4b17023SJohn Marino else if (! IS_DIR_SEPARATOR (endp[-1])) 794*e4b17023SJohn Marino { 795*e4b17023SJohn Marino nstore[endp-startp] = DIR_SEPARATOR; 796*e4b17023SJohn Marino nstore[endp-startp+1] = 0; 797*e4b17023SJohn Marino } 798*e4b17023SJohn Marino else 799*e4b17023SJohn Marino nstore[endp-startp] = 0; 800*e4b17023SJohn Marino 801*e4b17023SJohn Marino if (debug) 802*e4b17023SJohn Marino fprintf (stderr, " - add prefix: %s\n", nstore); 803*e4b17023SJohn Marino 804*e4b17023SJohn Marino add_prefix (pprefix, nstore); 805*e4b17023SJohn Marino if (*endp == 0) 806*e4b17023SJohn Marino break; 807*e4b17023SJohn Marino endp = startp = endp + 1; 808*e4b17023SJohn Marino } 809*e4b17023SJohn Marino else 810*e4b17023SJohn Marino endp++; 811*e4b17023SJohn Marino } 812*e4b17023SJohn Marino free (nstore); 813*e4b17023SJohn Marino } 814*e4b17023SJohn Marino 815*e4b17023SJohn Marino #ifdef OBJECT_FORMAT_NONE 816*e4b17023SJohn Marino 817*e4b17023SJohn Marino /* Add an entry for the object file NAME to object file list LIST. 818*e4b17023SJohn Marino New entries are added at the end of the list. The original pointer 819*e4b17023SJohn Marino value of NAME is preserved, i.e., no string copy is performed. */ 820*e4b17023SJohn Marino 821*e4b17023SJohn Marino static void 822*e4b17023SJohn Marino add_lto_object (struct lto_object_list *list, const char *name) 823*e4b17023SJohn Marino { 824*e4b17023SJohn Marino struct lto_object *n = XNEW (struct lto_object); 825*e4b17023SJohn Marino n->name = name; 826*e4b17023SJohn Marino n->next = NULL; 827*e4b17023SJohn Marino 828*e4b17023SJohn Marino if (list->last) 829*e4b17023SJohn Marino list->last->next = n; 830*e4b17023SJohn Marino else 831*e4b17023SJohn Marino list->first = n; 832*e4b17023SJohn Marino 833*e4b17023SJohn Marino list->last = n; 834*e4b17023SJohn Marino } 835*e4b17023SJohn Marino #endif /* OBJECT_FORMAT_NONE */ 836*e4b17023SJohn Marino 837*e4b17023SJohn Marino 838*e4b17023SJohn Marino /* Perform a link-time recompilation and relink if any of the object 839*e4b17023SJohn Marino files contain LTO info. The linker command line LTO_LD_ARGV 840*e4b17023SJohn Marino represents the linker command that would produce a final executable 841*e4b17023SJohn Marino without the use of LTO. OBJECT_LST is a vector of object file names 842*e4b17023SJohn Marino appearing in LTO_LD_ARGV that are to be considerd for link-time 843*e4b17023SJohn Marino recompilation, where OBJECT is a pointer to the last valid element. 844*e4b17023SJohn Marino (This awkward convention avoids an impedance mismatch with the 845*e4b17023SJohn Marino usage of similarly-named variables in main().) The elements of 846*e4b17023SJohn Marino OBJECT_LST must be identical, i.e., pointer equal, to the 847*e4b17023SJohn Marino corresponding arguments in LTO_LD_ARGV. 848*e4b17023SJohn Marino 849*e4b17023SJohn Marino Upon entry, at least one linker run has been performed without the 850*e4b17023SJohn Marino use of any LTO info that might be present. Any recompilations 851*e4b17023SJohn Marino necessary for template instantiations have been performed, and 852*e4b17023SJohn Marino initializer/finalizer tables have been created if needed and 853*e4b17023SJohn Marino included in the linker command line LTO_LD_ARGV. If any of the 854*e4b17023SJohn Marino object files contain LTO info, we run the LTO back end on all such 855*e4b17023SJohn Marino files, and perform the final link with the LTO back end output 856*e4b17023SJohn Marino substituted for the LTO-optimized files. In some cases, a final 857*e4b17023SJohn Marino link with all link-time generated code has already been performed, 858*e4b17023SJohn Marino so there is no need to relink if no LTO info is found. In other 859*e4b17023SJohn Marino cases, our caller has not produced the final executable, and is 860*e4b17023SJohn Marino relying on us to perform the required link whether LTO info is 861*e4b17023SJohn Marino present or not. In that case, the FORCE argument should be true. 862*e4b17023SJohn Marino Note that the linker command line argument LTO_LD_ARGV passed into 863*e4b17023SJohn Marino this function may be modified in place. */ 864*e4b17023SJohn Marino 865*e4b17023SJohn Marino static void 866*e4b17023SJohn Marino maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst, 867*e4b17023SJohn Marino const char **object, bool force) 868*e4b17023SJohn Marino { 869*e4b17023SJohn Marino const char **object_file = CONST_CAST2 (const char **, char **, object_lst); 870*e4b17023SJohn Marino 871*e4b17023SJohn Marino int num_lto_c_args = 1; /* Allow space for the terminating NULL. */ 872*e4b17023SJohn Marino 873*e4b17023SJohn Marino while (object_file < object) 874*e4b17023SJohn Marino { 875*e4b17023SJohn Marino /* If file contains LTO info, add it to the list of LTO objects. */ 876*e4b17023SJohn Marino scan_prog_file (*object_file++, PASS_LTOINFO, SCAN_ALL); 877*e4b17023SJohn Marino 878*e4b17023SJohn Marino /* Increment the argument count by the number of object file arguments 879*e4b17023SJohn Marino we will add. An upper bound suffices, so just count all of the 880*e4b17023SJohn Marino object files regardless of whether they contain LTO info. */ 881*e4b17023SJohn Marino num_lto_c_args++; 882*e4b17023SJohn Marino } 883*e4b17023SJohn Marino 884*e4b17023SJohn Marino if (lto_objects.first) 885*e4b17023SJohn Marino { 886*e4b17023SJohn Marino char **lto_c_argv; 887*e4b17023SJohn Marino const char **lto_c_ptr; 888*e4b17023SJohn Marino char **p; 889*e4b17023SJohn Marino char **lto_o_ptr; 890*e4b17023SJohn Marino struct lto_object *list; 891*e4b17023SJohn Marino char *lto_wrapper = getenv ("COLLECT_LTO_WRAPPER"); 892*e4b17023SJohn Marino struct pex_obj *pex; 893*e4b17023SJohn Marino const char *prog = "lto-wrapper"; 894*e4b17023SJohn Marino int lto_ld_argv_size = 0; 895*e4b17023SJohn Marino char **out_lto_ld_argv; 896*e4b17023SJohn Marino int out_lto_ld_argv_size; 897*e4b17023SJohn Marino size_t num_files; 898*e4b17023SJohn Marino 899*e4b17023SJohn Marino if (!lto_wrapper) 900*e4b17023SJohn Marino fatal_error ("COLLECT_LTO_WRAPPER must be set"); 901*e4b17023SJohn Marino 902*e4b17023SJohn Marino num_lto_c_args++; 903*e4b17023SJohn Marino 904*e4b17023SJohn Marino /* There is at least one object file containing LTO info, 905*e4b17023SJohn Marino so we need to run the LTO back end and relink. 906*e4b17023SJohn Marino 907*e4b17023SJohn Marino To do so we build updated ld arguments with first 908*e4b17023SJohn Marino LTO object replaced by all partitions and other LTO 909*e4b17023SJohn Marino objects removed. */ 910*e4b17023SJohn Marino 911*e4b17023SJohn Marino lto_c_argv = (char **) xcalloc (sizeof (char *), num_lto_c_args); 912*e4b17023SJohn Marino lto_c_ptr = CONST_CAST2 (const char **, char **, lto_c_argv); 913*e4b17023SJohn Marino 914*e4b17023SJohn Marino *lto_c_ptr++ = lto_wrapper; 915*e4b17023SJohn Marino 916*e4b17023SJohn Marino /* Add LTO objects to the wrapper command line. */ 917*e4b17023SJohn Marino for (list = lto_objects.first; list; list = list->next) 918*e4b17023SJohn Marino *lto_c_ptr++ = list->name; 919*e4b17023SJohn Marino 920*e4b17023SJohn Marino *lto_c_ptr = NULL; 921*e4b17023SJohn Marino 922*e4b17023SJohn Marino /* Run the LTO back end. */ 923*e4b17023SJohn Marino pex = collect_execute (prog, lto_c_argv, NULL, NULL, PEX_SEARCH); 924*e4b17023SJohn Marino { 925*e4b17023SJohn Marino int c; 926*e4b17023SJohn Marino FILE *stream; 927*e4b17023SJohn Marino size_t i; 928*e4b17023SJohn Marino char *start, *end; 929*e4b17023SJohn Marino 930*e4b17023SJohn Marino stream = pex_read_output (pex, 0); 931*e4b17023SJohn Marino gcc_assert (stream); 932*e4b17023SJohn Marino 933*e4b17023SJohn Marino num_files = 0; 934*e4b17023SJohn Marino while ((c = getc (stream)) != EOF) 935*e4b17023SJohn Marino { 936*e4b17023SJohn Marino obstack_1grow (&temporary_obstack, c); 937*e4b17023SJohn Marino if (c == '\n') 938*e4b17023SJohn Marino ++num_files; 939*e4b17023SJohn Marino } 940*e4b17023SJohn Marino 941*e4b17023SJohn Marino lto_o_files = XNEWVEC (char *, num_files + 1); 942*e4b17023SJohn Marino lto_o_files[num_files] = NULL; 943*e4b17023SJohn Marino start = XOBFINISH (&temporary_obstack, char *); 944*e4b17023SJohn Marino for (i = 0; i < num_files; ++i) 945*e4b17023SJohn Marino { 946*e4b17023SJohn Marino end = start; 947*e4b17023SJohn Marino while (*end != '\n') 948*e4b17023SJohn Marino ++end; 949*e4b17023SJohn Marino *end = '\0'; 950*e4b17023SJohn Marino 951*e4b17023SJohn Marino lto_o_files[i] = xstrdup (start); 952*e4b17023SJohn Marino 953*e4b17023SJohn Marino start = end + 1; 954*e4b17023SJohn Marino } 955*e4b17023SJohn Marino 956*e4b17023SJohn Marino obstack_free (&temporary_obstack, temporary_firstobj); 957*e4b17023SJohn Marino } 958*e4b17023SJohn Marino do_wait (prog, pex); 959*e4b17023SJohn Marino pex = NULL; 960*e4b17023SJohn Marino 961*e4b17023SJohn Marino /* Compute memory needed for new LD arguments. At most number of original arguemtns 962*e4b17023SJohn Marino plus number of partitions. */ 963*e4b17023SJohn Marino for (lto_ld_argv_size = 0; lto_ld_argv[lto_ld_argv_size]; lto_ld_argv_size++) 964*e4b17023SJohn Marino ; 965*e4b17023SJohn Marino out_lto_ld_argv = XCNEWVEC(char *, num_files + lto_ld_argv_size + 1); 966*e4b17023SJohn Marino out_lto_ld_argv_size = 0; 967*e4b17023SJohn Marino 968*e4b17023SJohn Marino /* After running the LTO back end, we will relink, substituting 969*e4b17023SJohn Marino the LTO output for the object files that we submitted to the 970*e4b17023SJohn Marino LTO. Here, we modify the linker command line for the relink. */ 971*e4b17023SJohn Marino 972*e4b17023SJohn Marino /* Copy all arguments until we find first LTO file. */ 973*e4b17023SJohn Marino p = lto_ld_argv; 974*e4b17023SJohn Marino while (*p != NULL) 975*e4b17023SJohn Marino { 976*e4b17023SJohn Marino for (list = lto_objects.first; list; list = list->next) 977*e4b17023SJohn Marino if (*p == list->name) /* Note test for pointer equality! */ 978*e4b17023SJohn Marino break; 979*e4b17023SJohn Marino if (list) 980*e4b17023SJohn Marino break; 981*e4b17023SJohn Marino out_lto_ld_argv[out_lto_ld_argv_size++] = *p++; 982*e4b17023SJohn Marino } 983*e4b17023SJohn Marino 984*e4b17023SJohn Marino /* Now insert all LTO partitions. */ 985*e4b17023SJohn Marino lto_o_ptr = lto_o_files; 986*e4b17023SJohn Marino while (*lto_o_ptr) 987*e4b17023SJohn Marino out_lto_ld_argv[out_lto_ld_argv_size++] = *lto_o_ptr++; 988*e4b17023SJohn Marino 989*e4b17023SJohn Marino /* ... and copy the rest. */ 990*e4b17023SJohn Marino while (*p != NULL) 991*e4b17023SJohn Marino { 992*e4b17023SJohn Marino for (list = lto_objects.first; list; list = list->next) 993*e4b17023SJohn Marino if (*p == list->name) /* Note test for pointer equality! */ 994*e4b17023SJohn Marino break; 995*e4b17023SJohn Marino if (!list) 996*e4b17023SJohn Marino out_lto_ld_argv[out_lto_ld_argv_size++] = *p; 997*e4b17023SJohn Marino p++; 998*e4b17023SJohn Marino } 999*e4b17023SJohn Marino out_lto_ld_argv[out_lto_ld_argv_size++] = 0; 1000*e4b17023SJohn Marino 1001*e4b17023SJohn Marino /* Run the linker again, this time replacing the object files 1002*e4b17023SJohn Marino optimized by the LTO with the temporary file generated by the LTO. */ 1003*e4b17023SJohn Marino fork_execute ("ld", out_lto_ld_argv); 1004*e4b17023SJohn Marino post_ld_pass (true); 1005*e4b17023SJohn Marino free (lto_ld_argv); 1006*e4b17023SJohn Marino 1007*e4b17023SJohn Marino maybe_unlink_list (lto_o_files); 1008*e4b17023SJohn Marino } 1009*e4b17023SJohn Marino else if (force) 1010*e4b17023SJohn Marino { 1011*e4b17023SJohn Marino /* Our caller is relying on us to do the link 1012*e4b17023SJohn Marino even though there is no LTO back end work to be done. */ 1013*e4b17023SJohn Marino fork_execute ("ld", lto_ld_argv); 1014*e4b17023SJohn Marino post_ld_pass (false); 1015*e4b17023SJohn Marino } 1016*e4b17023SJohn Marino } 1017*e4b17023SJohn Marino 1018*e4b17023SJohn Marino /* Main program. */ 1019*e4b17023SJohn Marino 1020*e4b17023SJohn Marino int 1021*e4b17023SJohn Marino main (int argc, char **argv) 1022*e4b17023SJohn Marino { 1023*e4b17023SJohn Marino static const char *const ld_suffix = "ld"; 1024*e4b17023SJohn Marino static const char *const plugin_ld_suffix = PLUGIN_LD; 1025*e4b17023SJohn Marino static const char *const real_ld_suffix = "real-ld"; 1026*e4b17023SJohn Marino static const char *const collect_ld_suffix = "collect-ld"; 1027*e4b17023SJohn Marino static const char *const nm_suffix = "nm"; 1028*e4b17023SJohn Marino static const char *const gnm_suffix = "gnm"; 1029*e4b17023SJohn Marino #ifdef LDD_SUFFIX 1030*e4b17023SJohn Marino static const char *const ldd_suffix = LDD_SUFFIX; 1031*e4b17023SJohn Marino #endif 1032*e4b17023SJohn Marino static const char *const strip_suffix = "strip"; 1033*e4b17023SJohn Marino static const char *const gstrip_suffix = "gstrip"; 1034*e4b17023SJohn Marino 1035*e4b17023SJohn Marino #ifdef CROSS_DIRECTORY_STRUCTURE 1036*e4b17023SJohn Marino /* If we look for a program in the compiler directories, we just use 1037*e4b17023SJohn Marino the short name, since these directories are already system-specific. 1038*e4b17023SJohn Marino But it we look for a program in the system directories, we need to 1039*e4b17023SJohn Marino qualify the program name with the target machine. */ 1040*e4b17023SJohn Marino 1041*e4b17023SJohn Marino const char *const full_ld_suffix = 1042*e4b17023SJohn Marino concat(target_machine, "-", ld_suffix, NULL); 1043*e4b17023SJohn Marino const char *const full_plugin_ld_suffix = 1044*e4b17023SJohn Marino concat(target_machine, "-", plugin_ld_suffix, NULL); 1045*e4b17023SJohn Marino const char *const full_nm_suffix = 1046*e4b17023SJohn Marino concat (target_machine, "-", nm_suffix, NULL); 1047*e4b17023SJohn Marino const char *const full_gnm_suffix = 1048*e4b17023SJohn Marino concat (target_machine, "-", gnm_suffix, NULL); 1049*e4b17023SJohn Marino #ifdef LDD_SUFFIX 1050*e4b17023SJohn Marino const char *const full_ldd_suffix = 1051*e4b17023SJohn Marino concat (target_machine, "-", ldd_suffix, NULL); 1052*e4b17023SJohn Marino #endif 1053*e4b17023SJohn Marino const char *const full_strip_suffix = 1054*e4b17023SJohn Marino concat (target_machine, "-", strip_suffix, NULL); 1055*e4b17023SJohn Marino const char *const full_gstrip_suffix = 1056*e4b17023SJohn Marino concat (target_machine, "-", gstrip_suffix, NULL); 1057*e4b17023SJohn Marino #else 1058*e4b17023SJohn Marino const char *const full_ld_suffix = ld_suffix; 1059*e4b17023SJohn Marino const char *const full_plugin_ld_suffix = plugin_ld_suffix; 1060*e4b17023SJohn Marino const char *const full_nm_suffix = nm_suffix; 1061*e4b17023SJohn Marino const char *const full_gnm_suffix = gnm_suffix; 1062*e4b17023SJohn Marino #ifdef LDD_SUFFIX 1063*e4b17023SJohn Marino const char *const full_ldd_suffix = ldd_suffix; 1064*e4b17023SJohn Marino #endif 1065*e4b17023SJohn Marino const char *const full_strip_suffix = strip_suffix; 1066*e4b17023SJohn Marino const char *const full_gstrip_suffix = gstrip_suffix; 1067*e4b17023SJohn Marino #endif /* CROSS_DIRECTORY_STRUCTURE */ 1068*e4b17023SJohn Marino 1069*e4b17023SJohn Marino const char *arg; 1070*e4b17023SJohn Marino FILE *outf; 1071*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1072*e4b17023SJohn Marino FILE *exportf; 1073*e4b17023SJohn Marino #endif 1074*e4b17023SJohn Marino const char *ld_file_name; 1075*e4b17023SJohn Marino const char *p; 1076*e4b17023SJohn Marino char **c_argv; 1077*e4b17023SJohn Marino const char **c_ptr; 1078*e4b17023SJohn Marino char **ld1_argv; 1079*e4b17023SJohn Marino const char **ld1; 1080*e4b17023SJohn Marino bool use_plugin = false; 1081*e4b17023SJohn Marino 1082*e4b17023SJohn Marino /* The kinds of symbols we will have to consider when scanning the 1083*e4b17023SJohn Marino outcome of a first pass link. This is ALL to start with, then might 1084*e4b17023SJohn Marino be adjusted before getting to the first pass link per se, typically on 1085*e4b17023SJohn Marino AIX where we perform an early scan of objects and libraries to fetch 1086*e4b17023SJohn Marino the list of global ctors/dtors and make sure they are not garbage 1087*e4b17023SJohn Marino collected. */ 1088*e4b17023SJohn Marino scanfilter ld1_filter = SCAN_ALL; 1089*e4b17023SJohn Marino 1090*e4b17023SJohn Marino char **ld2_argv; 1091*e4b17023SJohn Marino const char **ld2; 1092*e4b17023SJohn Marino char **object_lst; 1093*e4b17023SJohn Marino const char **object; 1094*e4b17023SJohn Marino #ifdef TARGET_AIX_VERSION 1095*e4b17023SJohn Marino int object_nbr = argc; 1096*e4b17023SJohn Marino #endif 1097*e4b17023SJohn Marino int first_file; 1098*e4b17023SJohn Marino int num_c_args; 1099*e4b17023SJohn Marino char **old_argv; 1100*e4b17023SJohn Marino 1101*e4b17023SJohn Marino p = argv[0] + strlen (argv[0]); 1102*e4b17023SJohn Marino while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1])) 1103*e4b17023SJohn Marino --p; 1104*e4b17023SJohn Marino progname = p; 1105*e4b17023SJohn Marino 1106*e4b17023SJohn Marino xmalloc_set_program_name (progname); 1107*e4b17023SJohn Marino 1108*e4b17023SJohn Marino old_argv = argv; 1109*e4b17023SJohn Marino expandargv (&argc, &argv); 1110*e4b17023SJohn Marino if (argv != old_argv) 1111*e4b17023SJohn Marino at_file_supplied = 1; 1112*e4b17023SJohn Marino 1113*e4b17023SJohn Marino process_args (&argc, argv); 1114*e4b17023SJohn Marino 1115*e4b17023SJohn Marino num_c_args = argc + 9; 1116*e4b17023SJohn Marino 1117*e4b17023SJohn Marino #ifndef HAVE_LD_DEMANGLE 1118*e4b17023SJohn Marino no_demangle = !! getenv ("COLLECT_NO_DEMANGLE"); 1119*e4b17023SJohn Marino 1120*e4b17023SJohn Marino /* Suppress demangling by the real linker, which may be broken. */ 1121*e4b17023SJohn Marino putenv (xstrdup ("COLLECT_NO_DEMANGLE=1")); 1122*e4b17023SJohn Marino #endif 1123*e4b17023SJohn Marino 1124*e4b17023SJohn Marino #if defined (COLLECT2_HOST_INITIALIZATION) 1125*e4b17023SJohn Marino /* Perform system dependent initialization, if necessary. */ 1126*e4b17023SJohn Marino COLLECT2_HOST_INITIALIZATION; 1127*e4b17023SJohn Marino #endif 1128*e4b17023SJohn Marino 1129*e4b17023SJohn Marino #ifdef SIGCHLD 1130*e4b17023SJohn Marino /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will 1131*e4b17023SJohn Marino receive the signal. A different setting is inheritable */ 1132*e4b17023SJohn Marino signal (SIGCHLD, SIG_DFL); 1133*e4b17023SJohn Marino #endif 1134*e4b17023SJohn Marino 1135*e4b17023SJohn Marino /* Unlock the stdio streams. */ 1136*e4b17023SJohn Marino unlock_std_streams (); 1137*e4b17023SJohn Marino 1138*e4b17023SJohn Marino gcc_init_libintl (); 1139*e4b17023SJohn Marino 1140*e4b17023SJohn Marino diagnostic_initialize (global_dc, 0); 1141*e4b17023SJohn Marino 1142*e4b17023SJohn Marino /* Do not invoke xcalloc before this point, since locale needs to be 1143*e4b17023SJohn Marino set first, in case a diagnostic is issued. */ 1144*e4b17023SJohn Marino 1145*e4b17023SJohn Marino ld1_argv = XCNEWVEC (char *, argc + 4); 1146*e4b17023SJohn Marino ld1 = CONST_CAST2 (const char **, char **, ld1_argv); 1147*e4b17023SJohn Marino ld2_argv = XCNEWVEC (char *, argc + 11); 1148*e4b17023SJohn Marino ld2 = CONST_CAST2 (const char **, char **, ld2_argv); 1149*e4b17023SJohn Marino object_lst = XCNEWVEC (char *, argc); 1150*e4b17023SJohn Marino object = CONST_CAST2 (const char **, char **, object_lst); 1151*e4b17023SJohn Marino 1152*e4b17023SJohn Marino #ifdef DEBUG 1153*e4b17023SJohn Marino debug = 1; 1154*e4b17023SJohn Marino #endif 1155*e4b17023SJohn Marino 1156*e4b17023SJohn Marino /* Parse command line early for instances of -debug. This allows 1157*e4b17023SJohn Marino the debug flag to be set before functions like find_a_file() 1158*e4b17023SJohn Marino are called. We also look for the -flto or -flto-partition=none flag to know 1159*e4b17023SJohn Marino what LTO mode we are in. */ 1160*e4b17023SJohn Marino { 1161*e4b17023SJohn Marino int i; 1162*e4b17023SJohn Marino bool no_partition = false; 1163*e4b17023SJohn Marino 1164*e4b17023SJohn Marino for (i = 1; argv[i] != NULL; i ++) 1165*e4b17023SJohn Marino { 1166*e4b17023SJohn Marino if (! strcmp (argv[i], "-debug")) 1167*e4b17023SJohn Marino debug = true; 1168*e4b17023SJohn Marino else if (! strcmp (argv[i], "-flto-partition=none")) 1169*e4b17023SJohn Marino no_partition = true; 1170*e4b17023SJohn Marino else if ((! strncmp (argv[i], "-flto=", 6) 1171*e4b17023SJohn Marino || ! strcmp (argv[i], "-flto")) && ! use_plugin) 1172*e4b17023SJohn Marino lto_mode = LTO_MODE_WHOPR; 1173*e4b17023SJohn Marino else if (!strncmp (argv[i], "-fno-lto", 8)) 1174*e4b17023SJohn Marino lto_mode = LTO_MODE_NONE; 1175*e4b17023SJohn Marino else if (! strcmp (argv[i], "-plugin")) 1176*e4b17023SJohn Marino { 1177*e4b17023SJohn Marino use_plugin = true; 1178*e4b17023SJohn Marino lto_mode = LTO_MODE_NONE; 1179*e4b17023SJohn Marino } 1180*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1181*e4b17023SJohn Marino /* since -brtl, -bexport, -b64 are not position dependent 1182*e4b17023SJohn Marino also check for them here */ 1183*e4b17023SJohn Marino if ((argv[i][0] == '-') && (argv[i][1] == 'b')) 1184*e4b17023SJohn Marino { 1185*e4b17023SJohn Marino arg = argv[i]; 1186*e4b17023SJohn Marino /* We want to disable automatic exports on AIX when user 1187*e4b17023SJohn Marino explicitly puts an export list in command line */ 1188*e4b17023SJohn Marino if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0) 1189*e4b17023SJohn Marino export_flag = 1; 1190*e4b17023SJohn Marino else if (arg[2] == '6' && arg[3] == '4') 1191*e4b17023SJohn Marino aix64_flag = 1; 1192*e4b17023SJohn Marino else if (arg[2] == 'r' && arg[3] == 't' && arg[4] == 'l') 1193*e4b17023SJohn Marino aixrtl_flag = 1; 1194*e4b17023SJohn Marino } 1195*e4b17023SJohn Marino #endif 1196*e4b17023SJohn Marino } 1197*e4b17023SJohn Marino vflag = debug; 1198*e4b17023SJohn Marino if (no_partition && lto_mode == LTO_MODE_WHOPR) 1199*e4b17023SJohn Marino lto_mode = LTO_MODE_LTO; 1200*e4b17023SJohn Marino } 1201*e4b17023SJohn Marino 1202*e4b17023SJohn Marino #ifndef DEFAULT_A_OUT_NAME 1203*e4b17023SJohn Marino output_file = "a.out"; 1204*e4b17023SJohn Marino #else 1205*e4b17023SJohn Marino output_file = DEFAULT_A_OUT_NAME; 1206*e4b17023SJohn Marino #endif 1207*e4b17023SJohn Marino 1208*e4b17023SJohn Marino obstack_begin (&temporary_obstack, 0); 1209*e4b17023SJohn Marino temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0); 1210*e4b17023SJohn Marino 1211*e4b17023SJohn Marino #ifndef HAVE_LD_DEMANGLE 1212*e4b17023SJohn Marino current_demangling_style = auto_demangling; 1213*e4b17023SJohn Marino #endif 1214*e4b17023SJohn Marino p = getenv ("COLLECT_GCC_OPTIONS"); 1215*e4b17023SJohn Marino while (p && *p) 1216*e4b17023SJohn Marino { 1217*e4b17023SJohn Marino const char *q = extract_string (&p); 1218*e4b17023SJohn Marino if (*q == '-' && (q[1] == 'm' || q[1] == 'f')) 1219*e4b17023SJohn Marino num_c_args++; 1220*e4b17023SJohn Marino } 1221*e4b17023SJohn Marino obstack_free (&temporary_obstack, temporary_firstobj); 1222*e4b17023SJohn Marino 1223*e4b17023SJohn Marino /* -fno-profile-arcs -fno-test-coverage -fno-branch-probabilities 1224*e4b17023SJohn Marino -fno-exceptions -w -fno-whole-program */ 1225*e4b17023SJohn Marino num_c_args += 6; 1226*e4b17023SJohn Marino 1227*e4b17023SJohn Marino c_argv = XCNEWVEC (char *, num_c_args); 1228*e4b17023SJohn Marino c_ptr = CONST_CAST2 (const char **, char **, c_argv); 1229*e4b17023SJohn Marino 1230*e4b17023SJohn Marino if (argc < 2) 1231*e4b17023SJohn Marino fatal_error ("no arguments"); 1232*e4b17023SJohn Marino 1233*e4b17023SJohn Marino #ifdef SIGQUIT 1234*e4b17023SJohn Marino if (signal (SIGQUIT, SIG_IGN) != SIG_IGN) 1235*e4b17023SJohn Marino signal (SIGQUIT, handler); 1236*e4b17023SJohn Marino #endif 1237*e4b17023SJohn Marino if (signal (SIGINT, SIG_IGN) != SIG_IGN) 1238*e4b17023SJohn Marino signal (SIGINT, handler); 1239*e4b17023SJohn Marino #ifdef SIGALRM 1240*e4b17023SJohn Marino if (signal (SIGALRM, SIG_IGN) != SIG_IGN) 1241*e4b17023SJohn Marino signal (SIGALRM, handler); 1242*e4b17023SJohn Marino #endif 1243*e4b17023SJohn Marino #ifdef SIGHUP 1244*e4b17023SJohn Marino if (signal (SIGHUP, SIG_IGN) != SIG_IGN) 1245*e4b17023SJohn Marino signal (SIGHUP, handler); 1246*e4b17023SJohn Marino #endif 1247*e4b17023SJohn Marino if (signal (SIGSEGV, SIG_IGN) != SIG_IGN) 1248*e4b17023SJohn Marino signal (SIGSEGV, handler); 1249*e4b17023SJohn Marino #ifdef SIGBUS 1250*e4b17023SJohn Marino if (signal (SIGBUS, SIG_IGN) != SIG_IGN) 1251*e4b17023SJohn Marino signal (SIGBUS, handler); 1252*e4b17023SJohn Marino #endif 1253*e4b17023SJohn Marino 1254*e4b17023SJohn Marino /* Extract COMPILER_PATH and PATH into our prefix list. */ 1255*e4b17023SJohn Marino prefix_from_env ("COMPILER_PATH", &cpath); 1256*e4b17023SJohn Marino prefix_from_env ("PATH", &path); 1257*e4b17023SJohn Marino 1258*e4b17023SJohn Marino /* Try to discover a valid linker/nm/strip to use. */ 1259*e4b17023SJohn Marino 1260*e4b17023SJohn Marino /* Maybe we know the right file to use (if not cross). */ 1261*e4b17023SJohn Marino ld_file_name = 0; 1262*e4b17023SJohn Marino #ifdef DEFAULT_LINKER 1263*e4b17023SJohn Marino if (access (DEFAULT_LINKER, X_OK) == 0) 1264*e4b17023SJohn Marino ld_file_name = DEFAULT_LINKER; 1265*e4b17023SJohn Marino if (ld_file_name == 0) 1266*e4b17023SJohn Marino #endif 1267*e4b17023SJohn Marino #ifdef REAL_LD_FILE_NAME 1268*e4b17023SJohn Marino ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME); 1269*e4b17023SJohn Marino if (ld_file_name == 0) 1270*e4b17023SJohn Marino #endif 1271*e4b17023SJohn Marino /* Search the (target-specific) compiler dirs for ld'. */ 1272*e4b17023SJohn Marino ld_file_name = find_a_file (&cpath, real_ld_suffix); 1273*e4b17023SJohn Marino /* Likewise for `collect-ld'. */ 1274*e4b17023SJohn Marino if (ld_file_name == 0) 1275*e4b17023SJohn Marino ld_file_name = find_a_file (&cpath, collect_ld_suffix); 1276*e4b17023SJohn Marino /* Search the compiler directories for `ld'. We have protection against 1277*e4b17023SJohn Marino recursive calls in find_a_file. */ 1278*e4b17023SJohn Marino if (ld_file_name == 0) 1279*e4b17023SJohn Marino ld_file_name = find_a_file (&cpath, 1280*e4b17023SJohn Marino use_plugin 1281*e4b17023SJohn Marino ? plugin_ld_suffix 1282*e4b17023SJohn Marino : ld_suffix); 1283*e4b17023SJohn Marino /* Search the ordinary system bin directories 1284*e4b17023SJohn Marino for `ld' (if native linking) or `TARGET-ld' (if cross). */ 1285*e4b17023SJohn Marino if (ld_file_name == 0) 1286*e4b17023SJohn Marino ld_file_name = find_a_file (&path, 1287*e4b17023SJohn Marino use_plugin 1288*e4b17023SJohn Marino ? full_plugin_ld_suffix 1289*e4b17023SJohn Marino : full_ld_suffix); 1290*e4b17023SJohn Marino 1291*e4b17023SJohn Marino #ifdef REAL_NM_FILE_NAME 1292*e4b17023SJohn Marino nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME); 1293*e4b17023SJohn Marino if (nm_file_name == 0) 1294*e4b17023SJohn Marino #endif 1295*e4b17023SJohn Marino nm_file_name = find_a_file (&cpath, gnm_suffix); 1296*e4b17023SJohn Marino if (nm_file_name == 0) 1297*e4b17023SJohn Marino nm_file_name = find_a_file (&path, full_gnm_suffix); 1298*e4b17023SJohn Marino if (nm_file_name == 0) 1299*e4b17023SJohn Marino nm_file_name = find_a_file (&cpath, nm_suffix); 1300*e4b17023SJohn Marino if (nm_file_name == 0) 1301*e4b17023SJohn Marino nm_file_name = find_a_file (&path, full_nm_suffix); 1302*e4b17023SJohn Marino 1303*e4b17023SJohn Marino #ifdef LDD_SUFFIX 1304*e4b17023SJohn Marino ldd_file_name = find_a_file (&cpath, ldd_suffix); 1305*e4b17023SJohn Marino if (ldd_file_name == 0) 1306*e4b17023SJohn Marino ldd_file_name = find_a_file (&path, full_ldd_suffix); 1307*e4b17023SJohn Marino #endif 1308*e4b17023SJohn Marino 1309*e4b17023SJohn Marino #ifdef REAL_STRIP_FILE_NAME 1310*e4b17023SJohn Marino strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME); 1311*e4b17023SJohn Marino if (strip_file_name == 0) 1312*e4b17023SJohn Marino #endif 1313*e4b17023SJohn Marino strip_file_name = find_a_file (&cpath, gstrip_suffix); 1314*e4b17023SJohn Marino if (strip_file_name == 0) 1315*e4b17023SJohn Marino strip_file_name = find_a_file (&path, full_gstrip_suffix); 1316*e4b17023SJohn Marino if (strip_file_name == 0) 1317*e4b17023SJohn Marino strip_file_name = find_a_file (&cpath, strip_suffix); 1318*e4b17023SJohn Marino if (strip_file_name == 0) 1319*e4b17023SJohn Marino strip_file_name = find_a_file (&path, full_strip_suffix); 1320*e4b17023SJohn Marino 1321*e4b17023SJohn Marino /* Determine the full path name of the C compiler to use. */ 1322*e4b17023SJohn Marino c_file_name = getenv ("COLLECT_GCC"); 1323*e4b17023SJohn Marino if (c_file_name == 0) 1324*e4b17023SJohn Marino { 1325*e4b17023SJohn Marino #ifdef CROSS_DIRECTORY_STRUCTURE 1326*e4b17023SJohn Marino c_file_name = concat (target_machine, "-gcc", NULL); 1327*e4b17023SJohn Marino #else 1328*e4b17023SJohn Marino c_file_name = "gcc"; 1329*e4b17023SJohn Marino #endif 1330*e4b17023SJohn Marino } 1331*e4b17023SJohn Marino 1332*e4b17023SJohn Marino p = find_a_file (&cpath, c_file_name); 1333*e4b17023SJohn Marino 1334*e4b17023SJohn Marino /* Here it should be safe to use the system search path since we should have 1335*e4b17023SJohn Marino already qualified the name of the compiler when it is needed. */ 1336*e4b17023SJohn Marino if (p == 0) 1337*e4b17023SJohn Marino p = find_a_file (&path, c_file_name); 1338*e4b17023SJohn Marino 1339*e4b17023SJohn Marino if (p) 1340*e4b17023SJohn Marino c_file_name = p; 1341*e4b17023SJohn Marino 1342*e4b17023SJohn Marino *ld1++ = *ld2++ = ld_file_name; 1343*e4b17023SJohn Marino 1344*e4b17023SJohn Marino /* Make temp file names. */ 1345*e4b17023SJohn Marino c_file = make_temp_file (".c"); 1346*e4b17023SJohn Marino o_file = make_temp_file (".o"); 1347*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1348*e4b17023SJohn Marino export_file = make_temp_file (".x"); 1349*e4b17023SJohn Marino #endif 1350*e4b17023SJohn Marino ldout = make_temp_file (".ld"); 1351*e4b17023SJohn Marino lderrout = make_temp_file (".le"); 1352*e4b17023SJohn Marino *c_ptr++ = c_file_name; 1353*e4b17023SJohn Marino *c_ptr++ = "-x"; 1354*e4b17023SJohn Marino *c_ptr++ = "c"; 1355*e4b17023SJohn Marino *c_ptr++ = "-c"; 1356*e4b17023SJohn Marino *c_ptr++ = "-o"; 1357*e4b17023SJohn Marino *c_ptr++ = o_file; 1358*e4b17023SJohn Marino 1359*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1360*e4b17023SJohn Marino /* Generate a list of directories from LIBPATH. */ 1361*e4b17023SJohn Marino prefix_from_env ("LIBPATH", &libpath_lib_dirs); 1362*e4b17023SJohn Marino /* Add to this list also two standard directories where 1363*e4b17023SJohn Marino AIX loader always searches for libraries. */ 1364*e4b17023SJohn Marino add_prefix (&libpath_lib_dirs, "/lib"); 1365*e4b17023SJohn Marino add_prefix (&libpath_lib_dirs, "/usr/lib"); 1366*e4b17023SJohn Marino #endif 1367*e4b17023SJohn Marino 1368*e4b17023SJohn Marino /* Get any options that the upper GCC wants to pass to the sub-GCC. 1369*e4b17023SJohn Marino 1370*e4b17023SJohn Marino AIX support needs to know if -shared has been specified before 1371*e4b17023SJohn Marino parsing commandline arguments. */ 1372*e4b17023SJohn Marino 1373*e4b17023SJohn Marino p = getenv ("COLLECT_GCC_OPTIONS"); 1374*e4b17023SJohn Marino while (p && *p) 1375*e4b17023SJohn Marino { 1376*e4b17023SJohn Marino const char *q = extract_string (&p); 1377*e4b17023SJohn Marino if (*q == '-' && (q[1] == 'm' || q[1] == 'f')) 1378*e4b17023SJohn Marino *c_ptr++ = xstrdup (q); 1379*e4b17023SJohn Marino if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0) 1380*e4b17023SJohn Marino *c_ptr++ = xstrdup (q); 1381*e4b17023SJohn Marino if (strcmp (q, "-shared") == 0) 1382*e4b17023SJohn Marino shared_obj = 1; 1383*e4b17023SJohn Marino if (*q == '-' && q[1] == 'B') 1384*e4b17023SJohn Marino { 1385*e4b17023SJohn Marino *c_ptr++ = xstrdup (q); 1386*e4b17023SJohn Marino if (q[2] == 0) 1387*e4b17023SJohn Marino { 1388*e4b17023SJohn Marino q = extract_string (&p); 1389*e4b17023SJohn Marino *c_ptr++ = xstrdup (q); 1390*e4b17023SJohn Marino } 1391*e4b17023SJohn Marino } 1392*e4b17023SJohn Marino } 1393*e4b17023SJohn Marino obstack_free (&temporary_obstack, temporary_firstobj); 1394*e4b17023SJohn Marino *c_ptr++ = "-fno-profile-arcs"; 1395*e4b17023SJohn Marino *c_ptr++ = "-fno-test-coverage"; 1396*e4b17023SJohn Marino *c_ptr++ = "-fno-branch-probabilities"; 1397*e4b17023SJohn Marino *c_ptr++ = "-fno-exceptions"; 1398*e4b17023SJohn Marino *c_ptr++ = "-w"; 1399*e4b17023SJohn Marino *c_ptr++ = "-fno-whole-program"; 1400*e4b17023SJohn Marino 1401*e4b17023SJohn Marino /* !!! When GCC calls collect2, 1402*e4b17023SJohn Marino it does not know whether it is calling collect2 or ld. 1403*e4b17023SJohn Marino So collect2 cannot meaningfully understand any options 1404*e4b17023SJohn Marino except those ld understands. 1405*e4b17023SJohn Marino If you propose to make GCC pass some other option, 1406*e4b17023SJohn Marino just imagine what will happen if ld is really ld!!! */ 1407*e4b17023SJohn Marino 1408*e4b17023SJohn Marino /* Parse arguments. Remember output file spec, pass the rest to ld. */ 1409*e4b17023SJohn Marino /* After the first file, put in the c++ rt0. */ 1410*e4b17023SJohn Marino 1411*e4b17023SJohn Marino first_file = 1; 1412*e4b17023SJohn Marino while ((arg = *++argv) != (char *) 0) 1413*e4b17023SJohn Marino { 1414*e4b17023SJohn Marino *ld1++ = *ld2++ = arg; 1415*e4b17023SJohn Marino 1416*e4b17023SJohn Marino if (arg[0] == '-') 1417*e4b17023SJohn Marino { 1418*e4b17023SJohn Marino switch (arg[1]) 1419*e4b17023SJohn Marino { 1420*e4b17023SJohn Marino case 'd': 1421*e4b17023SJohn Marino if (!strcmp (arg, "-debug")) 1422*e4b17023SJohn Marino { 1423*e4b17023SJohn Marino /* Already parsed. */ 1424*e4b17023SJohn Marino ld1--; 1425*e4b17023SJohn Marino ld2--; 1426*e4b17023SJohn Marino } 1427*e4b17023SJohn Marino if (!strcmp (arg, "-dynamic-linker") && argv[1]) 1428*e4b17023SJohn Marino { 1429*e4b17023SJohn Marino ++argv; 1430*e4b17023SJohn Marino *ld1++ = *ld2++ = *argv; 1431*e4b17023SJohn Marino } 1432*e4b17023SJohn Marino break; 1433*e4b17023SJohn Marino 1434*e4b17023SJohn Marino case 'f': 1435*e4b17023SJohn Marino if (strncmp (arg, "-flto", 5) == 0) 1436*e4b17023SJohn Marino { 1437*e4b17023SJohn Marino #ifdef ENABLE_LTO 1438*e4b17023SJohn Marino /* Do not pass LTO flag to the linker. */ 1439*e4b17023SJohn Marino ld1--; 1440*e4b17023SJohn Marino ld2--; 1441*e4b17023SJohn Marino #else 1442*e4b17023SJohn Marino error ("LTO support has not been enabled in this " 1443*e4b17023SJohn Marino "configuration"); 1444*e4b17023SJohn Marino #endif 1445*e4b17023SJohn Marino } 1446*e4b17023SJohn Marino #ifdef TARGET_AIX_VERSION 1447*e4b17023SJohn Marino else 1448*e4b17023SJohn Marino { 1449*e4b17023SJohn Marino /* File containing a list of input files to process. */ 1450*e4b17023SJohn Marino 1451*e4b17023SJohn Marino FILE *stream; 1452*e4b17023SJohn Marino char buf[MAXPATHLEN + 2]; 1453*e4b17023SJohn Marino /* Number of additionnal object files. */ 1454*e4b17023SJohn Marino int add_nbr = 0; 1455*e4b17023SJohn Marino /* Maximum of additionnal object files before vector 1456*e4b17023SJohn Marino expansion. */ 1457*e4b17023SJohn Marino int add_max = 0; 1458*e4b17023SJohn Marino const char *list_filename = arg + 2; 1459*e4b17023SJohn Marino 1460*e4b17023SJohn Marino /* Accept -fFILENAME and -f FILENAME. */ 1461*e4b17023SJohn Marino if (*list_filename == '\0' && argv[1]) 1462*e4b17023SJohn Marino { 1463*e4b17023SJohn Marino ++argv; 1464*e4b17023SJohn Marino list_filename = *argv; 1465*e4b17023SJohn Marino *ld1++ = *ld2++ = *argv; 1466*e4b17023SJohn Marino } 1467*e4b17023SJohn Marino 1468*e4b17023SJohn Marino stream = fopen (list_filename, "r"); 1469*e4b17023SJohn Marino if (stream == NULL) 1470*e4b17023SJohn Marino fatal_error ("can't open %s: %m", list_filename); 1471*e4b17023SJohn Marino 1472*e4b17023SJohn Marino while (fgets (buf, sizeof buf, stream) != NULL) 1473*e4b17023SJohn Marino { 1474*e4b17023SJohn Marino /* Remove end of line. */ 1475*e4b17023SJohn Marino int len = strlen (buf); 1476*e4b17023SJohn Marino if (len >= 1 && buf[len - 1] =='\n') 1477*e4b17023SJohn Marino buf[len - 1] = '\0'; 1478*e4b17023SJohn Marino 1479*e4b17023SJohn Marino /* Put on object vector. 1480*e4b17023SJohn Marino Note: we only expanse vector here, so we must keep 1481*e4b17023SJohn Marino extra space for remaining arguments. */ 1482*e4b17023SJohn Marino if (add_nbr >= add_max) 1483*e4b17023SJohn Marino { 1484*e4b17023SJohn Marino int pos = 1485*e4b17023SJohn Marino object - CONST_CAST2 (const char **, char **, 1486*e4b17023SJohn Marino object_lst); 1487*e4b17023SJohn Marino add_max = (add_max == 0) ? 16 : add_max * 2; 1488*e4b17023SJohn Marino object_lst = XRESIZEVEC (char *, object_lst, 1489*e4b17023SJohn Marino object_nbr + add_max); 1490*e4b17023SJohn Marino object = CONST_CAST2 (const char **, char **, 1491*e4b17023SJohn Marino object_lst) + pos; 1492*e4b17023SJohn Marino object_nbr += add_max; 1493*e4b17023SJohn Marino } 1494*e4b17023SJohn Marino *object++ = xstrdup (buf); 1495*e4b17023SJohn Marino add_nbr++; 1496*e4b17023SJohn Marino } 1497*e4b17023SJohn Marino fclose (stream); 1498*e4b17023SJohn Marino } 1499*e4b17023SJohn Marino #endif 1500*e4b17023SJohn Marino break; 1501*e4b17023SJohn Marino 1502*e4b17023SJohn Marino case 'l': 1503*e4b17023SJohn Marino if (first_file) 1504*e4b17023SJohn Marino { 1505*e4b17023SJohn Marino /* place o_file BEFORE this argument! */ 1506*e4b17023SJohn Marino first_file = 0; 1507*e4b17023SJohn Marino ld2--; 1508*e4b17023SJohn Marino *ld2++ = o_file; 1509*e4b17023SJohn Marino *ld2++ = arg; 1510*e4b17023SJohn Marino } 1511*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1512*e4b17023SJohn Marino { 1513*e4b17023SJohn Marino /* Resolving full library name. */ 1514*e4b17023SJohn Marino const char *s = resolve_lib_name (arg+2); 1515*e4b17023SJohn Marino 1516*e4b17023SJohn Marino /* Saving a full library name. */ 1517*e4b17023SJohn Marino add_to_list (&libs, s); 1518*e4b17023SJohn Marino } 1519*e4b17023SJohn Marino #endif 1520*e4b17023SJohn Marino break; 1521*e4b17023SJohn Marino 1522*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1523*e4b17023SJohn Marino /* Saving directories where to search for libraries. */ 1524*e4b17023SJohn Marino case 'L': 1525*e4b17023SJohn Marino add_prefix (&cmdline_lib_dirs, arg+2); 1526*e4b17023SJohn Marino break; 1527*e4b17023SJohn Marino #else 1528*e4b17023SJohn Marino #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES 1529*e4b17023SJohn Marino case 'L': 1530*e4b17023SJohn Marino if (is_in_args (arg, 1531*e4b17023SJohn Marino CONST_CAST2 (const char **, char **, ld1_argv), 1532*e4b17023SJohn Marino ld1 - 1)) 1533*e4b17023SJohn Marino --ld1; 1534*e4b17023SJohn Marino break; 1535*e4b17023SJohn Marino #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */ 1536*e4b17023SJohn Marino #endif 1537*e4b17023SJohn Marino 1538*e4b17023SJohn Marino case 'o': 1539*e4b17023SJohn Marino if (arg[2] == '\0') 1540*e4b17023SJohn Marino output_file = *ld1++ = *ld2++ = *++argv; 1541*e4b17023SJohn Marino else 1542*e4b17023SJohn Marino output_file = &arg[2]; 1543*e4b17023SJohn Marino break; 1544*e4b17023SJohn Marino 1545*e4b17023SJohn Marino case 'r': 1546*e4b17023SJohn Marino if (arg[2] == '\0') 1547*e4b17023SJohn Marino rflag = 1; 1548*e4b17023SJohn Marino break; 1549*e4b17023SJohn Marino 1550*e4b17023SJohn Marino case 's': 1551*e4b17023SJohn Marino if (arg[2] == '\0' && do_collecting) 1552*e4b17023SJohn Marino { 1553*e4b17023SJohn Marino /* We must strip after the nm run, otherwise C++ linking 1554*e4b17023SJohn Marino will not work. Thus we strip in the second ld run, or 1555*e4b17023SJohn Marino else with strip if there is no second ld run. */ 1556*e4b17023SJohn Marino strip_flag = 1; 1557*e4b17023SJohn Marino ld1--; 1558*e4b17023SJohn Marino } 1559*e4b17023SJohn Marino break; 1560*e4b17023SJohn Marino 1561*e4b17023SJohn Marino case 'v': 1562*e4b17023SJohn Marino if (arg[2] == '\0') 1563*e4b17023SJohn Marino vflag = true; 1564*e4b17023SJohn Marino break; 1565*e4b17023SJohn Marino 1566*e4b17023SJohn Marino case '-': 1567*e4b17023SJohn Marino if (strcmp (arg, "--no-demangle") == 0) 1568*e4b17023SJohn Marino { 1569*e4b17023SJohn Marino #ifndef HAVE_LD_DEMANGLE 1570*e4b17023SJohn Marino no_demangle = 1; 1571*e4b17023SJohn Marino ld1--; 1572*e4b17023SJohn Marino ld2--; 1573*e4b17023SJohn Marino #endif 1574*e4b17023SJohn Marino } 1575*e4b17023SJohn Marino else if (strncmp (arg, "--demangle", 10) == 0) 1576*e4b17023SJohn Marino { 1577*e4b17023SJohn Marino #ifndef HAVE_LD_DEMANGLE 1578*e4b17023SJohn Marino no_demangle = 0; 1579*e4b17023SJohn Marino if (arg[10] == '=') 1580*e4b17023SJohn Marino { 1581*e4b17023SJohn Marino enum demangling_styles style 1582*e4b17023SJohn Marino = cplus_demangle_name_to_style (arg+11); 1583*e4b17023SJohn Marino if (style == unknown_demangling) 1584*e4b17023SJohn Marino error ("unknown demangling style '%s'", arg+11); 1585*e4b17023SJohn Marino else 1586*e4b17023SJohn Marino current_demangling_style = style; 1587*e4b17023SJohn Marino } 1588*e4b17023SJohn Marino ld1--; 1589*e4b17023SJohn Marino ld2--; 1590*e4b17023SJohn Marino #endif 1591*e4b17023SJohn Marino } 1592*e4b17023SJohn Marino else if (strncmp (arg, "--sysroot=", 10) == 0) 1593*e4b17023SJohn Marino target_system_root = arg + 10; 1594*e4b17023SJohn Marino else if (strcmp (arg, "--version") == 0) 1595*e4b17023SJohn Marino vflag = true; 1596*e4b17023SJohn Marino else if (strcmp (arg, "--help") == 0) 1597*e4b17023SJohn Marino helpflag = true; 1598*e4b17023SJohn Marino break; 1599*e4b17023SJohn Marino } 1600*e4b17023SJohn Marino } 1601*e4b17023SJohn Marino else if ((p = strrchr (arg, '.')) != (char *) 0 1602*e4b17023SJohn Marino && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0 1603*e4b17023SJohn Marino || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0 1604*e4b17023SJohn Marino || strcmp (p, ".obj") == 0)) 1605*e4b17023SJohn Marino { 1606*e4b17023SJohn Marino if (first_file) 1607*e4b17023SJohn Marino { 1608*e4b17023SJohn Marino first_file = 0; 1609*e4b17023SJohn Marino if (p[1] == 'o') 1610*e4b17023SJohn Marino *ld2++ = o_file; 1611*e4b17023SJohn Marino else 1612*e4b17023SJohn Marino { 1613*e4b17023SJohn Marino /* place o_file BEFORE this argument! */ 1614*e4b17023SJohn Marino ld2--; 1615*e4b17023SJohn Marino *ld2++ = o_file; 1616*e4b17023SJohn Marino *ld2++ = arg; 1617*e4b17023SJohn Marino } 1618*e4b17023SJohn Marino } 1619*e4b17023SJohn Marino if (p[1] == 'o' || p[1] == 'l') 1620*e4b17023SJohn Marino *object++ = arg; 1621*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1622*e4b17023SJohn Marino /* libraries can be specified directly, i.e. without -l flag. */ 1623*e4b17023SJohn Marino else 1624*e4b17023SJohn Marino { 1625*e4b17023SJohn Marino /* Saving a full library name. */ 1626*e4b17023SJohn Marino add_to_list (&libs, arg); 1627*e4b17023SJohn Marino } 1628*e4b17023SJohn Marino #endif 1629*e4b17023SJohn Marino } 1630*e4b17023SJohn Marino } 1631*e4b17023SJohn Marino 1632*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1633*e4b17023SJohn Marino /* This is added only for debugging purposes. */ 1634*e4b17023SJohn Marino if (debug) 1635*e4b17023SJohn Marino { 1636*e4b17023SJohn Marino fprintf (stderr, "List of libraries:\n"); 1637*e4b17023SJohn Marino dump_list (stderr, "\t", libs.first); 1638*e4b17023SJohn Marino } 1639*e4b17023SJohn Marino 1640*e4b17023SJohn Marino /* The AIX linker will discard static constructors in object files if 1641*e4b17023SJohn Marino nothing else in the file is referenced, so look at them first. Unless 1642*e4b17023SJohn Marino we are building a shared object, ignore the eh frame tables, as we 1643*e4b17023SJohn Marino would otherwise reference them all, hence drag all the corresponding 1644*e4b17023SJohn Marino objects even if nothing else is referenced. */ 1645*e4b17023SJohn Marino { 1646*e4b17023SJohn Marino const char **export_object_lst 1647*e4b17023SJohn Marino = CONST_CAST2 (const char **, char **, object_lst); 1648*e4b17023SJohn Marino 1649*e4b17023SJohn Marino struct id *list = libs.first; 1650*e4b17023SJohn Marino 1651*e4b17023SJohn Marino /* Compute the filter to use from the current one, do scan, then adjust 1652*e4b17023SJohn Marino the "current" filter to remove what we just included here. This will 1653*e4b17023SJohn Marino control whether we need a first pass link later on or not, and what 1654*e4b17023SJohn Marino will remain to be scanned there. */ 1655*e4b17023SJohn Marino 1656*e4b17023SJohn Marino scanfilter this_filter = ld1_filter; 1657*e4b17023SJohn Marino #if HAVE_AS_REF 1658*e4b17023SJohn Marino if (!shared_obj) 1659*e4b17023SJohn Marino this_filter &= ~SCAN_DWEH; 1660*e4b17023SJohn Marino #endif 1661*e4b17023SJohn Marino 1662*e4b17023SJohn Marino while (export_object_lst < object) 1663*e4b17023SJohn Marino scan_prog_file (*export_object_lst++, PASS_OBJ, this_filter); 1664*e4b17023SJohn Marino 1665*e4b17023SJohn Marino for (; list; list = list->next) 1666*e4b17023SJohn Marino scan_prog_file (list->name, PASS_FIRST, this_filter); 1667*e4b17023SJohn Marino 1668*e4b17023SJohn Marino ld1_filter = ld1_filter & ~this_filter; 1669*e4b17023SJohn Marino } 1670*e4b17023SJohn Marino 1671*e4b17023SJohn Marino if (exports.first) 1672*e4b17023SJohn Marino { 1673*e4b17023SJohn Marino char *buf = concat ("-bE:", export_file, NULL); 1674*e4b17023SJohn Marino 1675*e4b17023SJohn Marino *ld1++ = buf; 1676*e4b17023SJohn Marino *ld2++ = buf; 1677*e4b17023SJohn Marino 1678*e4b17023SJohn Marino exportf = fopen (export_file, "w"); 1679*e4b17023SJohn Marino if (exportf == (FILE *) 0) 1680*e4b17023SJohn Marino fatal_error ("fopen %s: %m", export_file); 1681*e4b17023SJohn Marino write_aix_file (exportf, exports.first); 1682*e4b17023SJohn Marino if (fclose (exportf)) 1683*e4b17023SJohn Marino fatal_error ("fclose %s: %m", export_file); 1684*e4b17023SJohn Marino } 1685*e4b17023SJohn Marino #endif 1686*e4b17023SJohn Marino 1687*e4b17023SJohn Marino *c_ptr++ = c_file; 1688*e4b17023SJohn Marino *c_ptr = *ld1 = *object = (char *) 0; 1689*e4b17023SJohn Marino 1690*e4b17023SJohn Marino if (vflag) 1691*e4b17023SJohn Marino notice ("collect2 version %s\n", version_string); 1692*e4b17023SJohn Marino 1693*e4b17023SJohn Marino if (helpflag) 1694*e4b17023SJohn Marino { 1695*e4b17023SJohn Marino printf ("Usage: collect2 [options]\n"); 1696*e4b17023SJohn Marino printf (" Wrap linker and generate constructor code if needed.\n"); 1697*e4b17023SJohn Marino printf (" Options:\n"); 1698*e4b17023SJohn Marino printf (" -debug Enable debug output\n"); 1699*e4b17023SJohn Marino printf (" --help Display this information\n"); 1700*e4b17023SJohn Marino printf (" -v, --version Display this program's version number\n"); 1701*e4b17023SJohn Marino printf ("\n"); 1702*e4b17023SJohn Marino printf ("Overview: http://gcc.gnu.org/onlinedocs/gccint/Collect2.html\n"); 1703*e4b17023SJohn Marino printf ("Report bugs: %s\n", bug_report_url); 1704*e4b17023SJohn Marino printf ("\n"); 1705*e4b17023SJohn Marino } 1706*e4b17023SJohn Marino 1707*e4b17023SJohn Marino if (debug) 1708*e4b17023SJohn Marino { 1709*e4b17023SJohn Marino const char *ptr; 1710*e4b17023SJohn Marino fprintf (stderr, "ld_file_name = %s\n", 1711*e4b17023SJohn Marino (ld_file_name ? ld_file_name : "not found")); 1712*e4b17023SJohn Marino fprintf (stderr, "c_file_name = %s\n", 1713*e4b17023SJohn Marino (c_file_name ? c_file_name : "not found")); 1714*e4b17023SJohn Marino fprintf (stderr, "nm_file_name = %s\n", 1715*e4b17023SJohn Marino (nm_file_name ? nm_file_name : "not found")); 1716*e4b17023SJohn Marino #ifdef LDD_SUFFIX 1717*e4b17023SJohn Marino fprintf (stderr, "ldd_file_name = %s\n", 1718*e4b17023SJohn Marino (ldd_file_name ? ldd_file_name : "not found")); 1719*e4b17023SJohn Marino #endif 1720*e4b17023SJohn Marino fprintf (stderr, "strip_file_name = %s\n", 1721*e4b17023SJohn Marino (strip_file_name ? strip_file_name : "not found")); 1722*e4b17023SJohn Marino fprintf (stderr, "c_file = %s\n", 1723*e4b17023SJohn Marino (c_file ? c_file : "not found")); 1724*e4b17023SJohn Marino fprintf (stderr, "o_file = %s\n", 1725*e4b17023SJohn Marino (o_file ? o_file : "not found")); 1726*e4b17023SJohn Marino 1727*e4b17023SJohn Marino ptr = getenv ("COLLECT_GCC_OPTIONS"); 1728*e4b17023SJohn Marino if (ptr) 1729*e4b17023SJohn Marino fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr); 1730*e4b17023SJohn Marino 1731*e4b17023SJohn Marino ptr = getenv ("COLLECT_GCC"); 1732*e4b17023SJohn Marino if (ptr) 1733*e4b17023SJohn Marino fprintf (stderr, "COLLECT_GCC = %s\n", ptr); 1734*e4b17023SJohn Marino 1735*e4b17023SJohn Marino ptr = getenv ("COMPILER_PATH"); 1736*e4b17023SJohn Marino if (ptr) 1737*e4b17023SJohn Marino fprintf (stderr, "COMPILER_PATH = %s\n", ptr); 1738*e4b17023SJohn Marino 1739*e4b17023SJohn Marino ptr = getenv (LIBRARY_PATH_ENV); 1740*e4b17023SJohn Marino if (ptr) 1741*e4b17023SJohn Marino fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr); 1742*e4b17023SJohn Marino 1743*e4b17023SJohn Marino fprintf (stderr, "\n"); 1744*e4b17023SJohn Marino } 1745*e4b17023SJohn Marino 1746*e4b17023SJohn Marino /* Load the program, searching all libraries and attempting to provide 1747*e4b17023SJohn Marino undefined symbols from repository information. 1748*e4b17023SJohn Marino 1749*e4b17023SJohn Marino If -r or they will be run via some other method, do not build the 1750*e4b17023SJohn Marino constructor or destructor list, just return now. */ 1751*e4b17023SJohn Marino { 1752*e4b17023SJohn Marino bool early_exit 1753*e4b17023SJohn Marino = rflag || (! DO_COLLECT_EXPORT_LIST && ! do_collecting); 1754*e4b17023SJohn Marino 1755*e4b17023SJohn Marino /* Perform the first pass link now, if we're about to exit or if we need 1756*e4b17023SJohn Marino to scan for things we haven't collected yet before pursuing further. 1757*e4b17023SJohn Marino 1758*e4b17023SJohn Marino On AIX, the latter typically includes nothing for shared objects or 1759*e4b17023SJohn Marino frame tables for an executable, out of what the required early scan on 1760*e4b17023SJohn Marino objects and libraries has performed above. In the !shared_obj case, we 1761*e4b17023SJohn Marino expect the relevant tables to be dragged together with their associated 1762*e4b17023SJohn Marino functions from precise cross reference insertions by the compiler. */ 1763*e4b17023SJohn Marino 1764*e4b17023SJohn Marino if (early_exit || ld1_filter != SCAN_NOTHING) 1765*e4b17023SJohn Marino do_tlink (ld1_argv, object_lst); 1766*e4b17023SJohn Marino 1767*e4b17023SJohn Marino if (early_exit) 1768*e4b17023SJohn Marino { 1769*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1770*e4b17023SJohn Marino /* Make sure we delete the export file we may have created. */ 1771*e4b17023SJohn Marino if (export_file != 0 && export_file[0]) 1772*e4b17023SJohn Marino maybe_unlink (export_file); 1773*e4b17023SJohn Marino #endif 1774*e4b17023SJohn Marino if (lto_mode != LTO_MODE_NONE) 1775*e4b17023SJohn Marino maybe_run_lto_and_relink (ld1_argv, object_lst, object, false); 1776*e4b17023SJohn Marino else 1777*e4b17023SJohn Marino post_ld_pass (false); 1778*e4b17023SJohn Marino 1779*e4b17023SJohn Marino maybe_unlink (c_file); 1780*e4b17023SJohn Marino maybe_unlink (o_file); 1781*e4b17023SJohn Marino return 0; 1782*e4b17023SJohn Marino } 1783*e4b17023SJohn Marino } 1784*e4b17023SJohn Marino 1785*e4b17023SJohn Marino /* Unless we have done it all already, examine the namelist and search for 1786*e4b17023SJohn Marino static constructors and destructors to call. Write the constructor and 1787*e4b17023SJohn Marino destructor tables to a .s file and reload. */ 1788*e4b17023SJohn Marino 1789*e4b17023SJohn Marino if (ld1_filter != SCAN_NOTHING) 1790*e4b17023SJohn Marino scan_prog_file (output_file, PASS_FIRST, ld1_filter); 1791*e4b17023SJohn Marino 1792*e4b17023SJohn Marino #ifdef SCAN_LIBRARIES 1793*e4b17023SJohn Marino scan_libraries (output_file); 1794*e4b17023SJohn Marino #endif 1795*e4b17023SJohn Marino 1796*e4b17023SJohn Marino if (debug) 1797*e4b17023SJohn Marino { 1798*e4b17023SJohn Marino notice_translated (ngettext ("%d constructor found\n", 1799*e4b17023SJohn Marino "%d constructors found\n", 1800*e4b17023SJohn Marino constructors.number), 1801*e4b17023SJohn Marino constructors.number); 1802*e4b17023SJohn Marino notice_translated (ngettext ("%d destructor found\n", 1803*e4b17023SJohn Marino "%d destructors found\n", 1804*e4b17023SJohn Marino destructors.number), 1805*e4b17023SJohn Marino destructors.number); 1806*e4b17023SJohn Marino notice_translated (ngettext("%d frame table found\n", 1807*e4b17023SJohn Marino "%d frame tables found\n", 1808*e4b17023SJohn Marino frame_tables.number), 1809*e4b17023SJohn Marino frame_tables.number); 1810*e4b17023SJohn Marino } 1811*e4b17023SJohn Marino 1812*e4b17023SJohn Marino /* If the scan exposed nothing of special interest, there's no need to 1813*e4b17023SJohn Marino generate the glue code and relink so return now. */ 1814*e4b17023SJohn Marino 1815*e4b17023SJohn Marino if (constructors.number == 0 && destructors.number == 0 1816*e4b17023SJohn Marino && frame_tables.number == 0 1817*e4b17023SJohn Marino #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST) 1818*e4b17023SJohn Marino /* If we will be running these functions ourselves, we want to emit 1819*e4b17023SJohn Marino stubs into the shared library so that we do not have to relink 1820*e4b17023SJohn Marino dependent programs when we add static objects. */ 1821*e4b17023SJohn Marino && ! shared_obj 1822*e4b17023SJohn Marino #endif 1823*e4b17023SJohn Marino ) 1824*e4b17023SJohn Marino { 1825*e4b17023SJohn Marino /* Do tlink without additional code generation now if we didn't 1826*e4b17023SJohn Marino do it earlier for scanning purposes. */ 1827*e4b17023SJohn Marino if (ld1_filter == SCAN_NOTHING) 1828*e4b17023SJohn Marino do_tlink (ld1_argv, object_lst); 1829*e4b17023SJohn Marino 1830*e4b17023SJohn Marino if (lto_mode) 1831*e4b17023SJohn Marino maybe_run_lto_and_relink (ld1_argv, object_lst, object, false); 1832*e4b17023SJohn Marino 1833*e4b17023SJohn Marino /* Strip now if it was requested on the command line. */ 1834*e4b17023SJohn Marino if (strip_flag) 1835*e4b17023SJohn Marino { 1836*e4b17023SJohn Marino char **real_strip_argv = XCNEWVEC (char *, 3); 1837*e4b17023SJohn Marino const char ** strip_argv = CONST_CAST2 (const char **, char **, 1838*e4b17023SJohn Marino real_strip_argv); 1839*e4b17023SJohn Marino 1840*e4b17023SJohn Marino strip_argv[0] = strip_file_name; 1841*e4b17023SJohn Marino strip_argv[1] = output_file; 1842*e4b17023SJohn Marino strip_argv[2] = (char *) 0; 1843*e4b17023SJohn Marino fork_execute ("strip", real_strip_argv); 1844*e4b17023SJohn Marino } 1845*e4b17023SJohn Marino 1846*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1847*e4b17023SJohn Marino maybe_unlink (export_file); 1848*e4b17023SJohn Marino #endif 1849*e4b17023SJohn Marino post_ld_pass (false); 1850*e4b17023SJohn Marino 1851*e4b17023SJohn Marino maybe_unlink (c_file); 1852*e4b17023SJohn Marino maybe_unlink (o_file); 1853*e4b17023SJohn Marino return 0; 1854*e4b17023SJohn Marino } 1855*e4b17023SJohn Marino 1856*e4b17023SJohn Marino /* Sort ctor and dtor lists by priority. */ 1857*e4b17023SJohn Marino sort_ids (&constructors); 1858*e4b17023SJohn Marino sort_ids (&destructors); 1859*e4b17023SJohn Marino 1860*e4b17023SJohn Marino maybe_unlink(output_file); 1861*e4b17023SJohn Marino outf = fopen (c_file, "w"); 1862*e4b17023SJohn Marino if (outf == (FILE *) 0) 1863*e4b17023SJohn Marino fatal_error ("fopen %s: %m", c_file); 1864*e4b17023SJohn Marino 1865*e4b17023SJohn Marino write_c_file (outf, c_file); 1866*e4b17023SJohn Marino 1867*e4b17023SJohn Marino if (fclose (outf)) 1868*e4b17023SJohn Marino fatal_error ("fclose %s: %m", c_file); 1869*e4b17023SJohn Marino 1870*e4b17023SJohn Marino /* Tell the linker that we have initializer and finalizer functions. */ 1871*e4b17023SJohn Marino #ifdef LD_INIT_SWITCH 1872*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1873*e4b17023SJohn Marino *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL); 1874*e4b17023SJohn Marino #else 1875*e4b17023SJohn Marino *ld2++ = LD_INIT_SWITCH; 1876*e4b17023SJohn Marino *ld2++ = initname; 1877*e4b17023SJohn Marino *ld2++ = LD_FINI_SWITCH; 1878*e4b17023SJohn Marino *ld2++ = fininame; 1879*e4b17023SJohn Marino #endif 1880*e4b17023SJohn Marino #endif 1881*e4b17023SJohn Marino 1882*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1883*e4b17023SJohn Marino if (shared_obj) 1884*e4b17023SJohn Marino { 1885*e4b17023SJohn Marino /* If we did not add export flag to link arguments before, add it to 1886*e4b17023SJohn Marino second link phase now. No new exports should have been added. */ 1887*e4b17023SJohn Marino if (! exports.first) 1888*e4b17023SJohn Marino *ld2++ = concat ("-bE:", export_file, NULL); 1889*e4b17023SJohn Marino 1890*e4b17023SJohn Marino #ifndef LD_INIT_SWITCH 1891*e4b17023SJohn Marino add_to_list (&exports, initname); 1892*e4b17023SJohn Marino add_to_list (&exports, fininame); 1893*e4b17023SJohn Marino add_to_list (&exports, "_GLOBAL__DI"); 1894*e4b17023SJohn Marino add_to_list (&exports, "_GLOBAL__DD"); 1895*e4b17023SJohn Marino #endif 1896*e4b17023SJohn Marino exportf = fopen (export_file, "w"); 1897*e4b17023SJohn Marino if (exportf == (FILE *) 0) 1898*e4b17023SJohn Marino fatal_error ("fopen %s: %m", export_file); 1899*e4b17023SJohn Marino write_aix_file (exportf, exports.first); 1900*e4b17023SJohn Marino if (fclose (exportf)) 1901*e4b17023SJohn Marino fatal_error ("fclose %s: %m", export_file); 1902*e4b17023SJohn Marino } 1903*e4b17023SJohn Marino #endif 1904*e4b17023SJohn Marino 1905*e4b17023SJohn Marino /* End of arguments to second link phase. */ 1906*e4b17023SJohn Marino *ld2 = (char*) 0; 1907*e4b17023SJohn Marino 1908*e4b17023SJohn Marino if (debug) 1909*e4b17023SJohn Marino { 1910*e4b17023SJohn Marino fprintf (stderr, "\n========== output_file = %s, c_file = %s\n", 1911*e4b17023SJohn Marino output_file, c_file); 1912*e4b17023SJohn Marino write_c_file (stderr, "stderr"); 1913*e4b17023SJohn Marino fprintf (stderr, "========== end of c_file\n\n"); 1914*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1915*e4b17023SJohn Marino fprintf (stderr, "\n========== export_file = %s\n", export_file); 1916*e4b17023SJohn Marino write_aix_file (stderr, exports.first); 1917*e4b17023SJohn Marino fprintf (stderr, "========== end of export_file\n\n"); 1918*e4b17023SJohn Marino #endif 1919*e4b17023SJohn Marino } 1920*e4b17023SJohn Marino 1921*e4b17023SJohn Marino /* Assemble the constructor and destructor tables. 1922*e4b17023SJohn Marino Link the tables in with the rest of the program. */ 1923*e4b17023SJohn Marino 1924*e4b17023SJohn Marino fork_execute ("gcc", c_argv); 1925*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1926*e4b17023SJohn Marino /* On AIX we must call tlink because of possible templates resolution. */ 1927*e4b17023SJohn Marino do_tlink (ld2_argv, object_lst); 1928*e4b17023SJohn Marino 1929*e4b17023SJohn Marino if (lto_mode) 1930*e4b17023SJohn Marino maybe_run_lto_and_relink (ld2_argv, object_lst, object, false); 1931*e4b17023SJohn Marino #else 1932*e4b17023SJohn Marino /* Otherwise, simply call ld because tlink is already done. */ 1933*e4b17023SJohn Marino if (lto_mode) 1934*e4b17023SJohn Marino maybe_run_lto_and_relink (ld2_argv, object_lst, object, true); 1935*e4b17023SJohn Marino else 1936*e4b17023SJohn Marino { 1937*e4b17023SJohn Marino fork_execute ("ld", ld2_argv); 1938*e4b17023SJohn Marino post_ld_pass (false); 1939*e4b17023SJohn Marino } 1940*e4b17023SJohn Marino 1941*e4b17023SJohn Marino /* Let scan_prog_file do any final mods (OSF/rose needs this for 1942*e4b17023SJohn Marino constructors/destructors in shared libraries. */ 1943*e4b17023SJohn Marino scan_prog_file (output_file, PASS_SECOND, SCAN_ALL); 1944*e4b17023SJohn Marino #endif 1945*e4b17023SJohn Marino 1946*e4b17023SJohn Marino maybe_unlink (c_file); 1947*e4b17023SJohn Marino maybe_unlink (o_file); 1948*e4b17023SJohn Marino 1949*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 1950*e4b17023SJohn Marino maybe_unlink (export_file); 1951*e4b17023SJohn Marino #endif 1952*e4b17023SJohn Marino 1953*e4b17023SJohn Marino return 0; 1954*e4b17023SJohn Marino } 1955*e4b17023SJohn Marino 1956*e4b17023SJohn Marino 1957*e4b17023SJohn Marino /* Wait for a process to finish, and exit if a nonzero status is found. */ 1958*e4b17023SJohn Marino 1959*e4b17023SJohn Marino int 1960*e4b17023SJohn Marino collect_wait (const char *prog, struct pex_obj *pex) 1961*e4b17023SJohn Marino { 1962*e4b17023SJohn Marino int status; 1963*e4b17023SJohn Marino 1964*e4b17023SJohn Marino if (!pex_get_status (pex, 1, &status)) 1965*e4b17023SJohn Marino fatal_error ("can't get program status: %m"); 1966*e4b17023SJohn Marino pex_free (pex); 1967*e4b17023SJohn Marino 1968*e4b17023SJohn Marino if (status) 1969*e4b17023SJohn Marino { 1970*e4b17023SJohn Marino if (WIFSIGNALED (status)) 1971*e4b17023SJohn Marino { 1972*e4b17023SJohn Marino int sig = WTERMSIG (status); 1973*e4b17023SJohn Marino error ("%s terminated with signal %d [%s]%s", 1974*e4b17023SJohn Marino prog, sig, strsignal(sig), 1975*e4b17023SJohn Marino WCOREDUMP(status) ? ", core dumped" : ""); 1976*e4b17023SJohn Marino collect_exit (FATAL_EXIT_CODE); 1977*e4b17023SJohn Marino } 1978*e4b17023SJohn Marino 1979*e4b17023SJohn Marino if (WIFEXITED (status)) 1980*e4b17023SJohn Marino return WEXITSTATUS (status); 1981*e4b17023SJohn Marino } 1982*e4b17023SJohn Marino return 0; 1983*e4b17023SJohn Marino } 1984*e4b17023SJohn Marino 1985*e4b17023SJohn Marino static void 1986*e4b17023SJohn Marino do_wait (const char *prog, struct pex_obj *pex) 1987*e4b17023SJohn Marino { 1988*e4b17023SJohn Marino int ret = collect_wait (prog, pex); 1989*e4b17023SJohn Marino if (ret != 0) 1990*e4b17023SJohn Marino { 1991*e4b17023SJohn Marino error ("%s returned %d exit status", prog, ret); 1992*e4b17023SJohn Marino collect_exit (ret); 1993*e4b17023SJohn Marino } 1994*e4b17023SJohn Marino 1995*e4b17023SJohn Marino if (response_file) 1996*e4b17023SJohn Marino { 1997*e4b17023SJohn Marino unlink (response_file); 1998*e4b17023SJohn Marino response_file = NULL; 1999*e4b17023SJohn Marino } 2000*e4b17023SJohn Marino } 2001*e4b17023SJohn Marino 2002*e4b17023SJohn Marino 2003*e4b17023SJohn Marino /* Execute a program, and wait for the reply. */ 2004*e4b17023SJohn Marino 2005*e4b17023SJohn Marino struct pex_obj * 2006*e4b17023SJohn Marino collect_execute (const char *prog, char **argv, const char *outname, 2007*e4b17023SJohn Marino const char *errname, int flags) 2008*e4b17023SJohn Marino { 2009*e4b17023SJohn Marino struct pex_obj *pex; 2010*e4b17023SJohn Marino const char *errmsg; 2011*e4b17023SJohn Marino int err; 2012*e4b17023SJohn Marino char *response_arg = NULL; 2013*e4b17023SJohn Marino char *response_argv[3] ATTRIBUTE_UNUSED; 2014*e4b17023SJohn Marino 2015*e4b17023SJohn Marino if (HAVE_GNU_LD && at_file_supplied && argv[0] != NULL) 2016*e4b17023SJohn Marino { 2017*e4b17023SJohn Marino /* If using @file arguments, create a temporary file and put the 2018*e4b17023SJohn Marino contents of argv into it. Then change argv to an array corresponding 2019*e4b17023SJohn Marino to a single argument @FILE, where FILE is the temporary filename. */ 2020*e4b17023SJohn Marino 2021*e4b17023SJohn Marino char **current_argv = argv + 1; 2022*e4b17023SJohn Marino char *argv0 = argv[0]; 2023*e4b17023SJohn Marino int status; 2024*e4b17023SJohn Marino FILE *f; 2025*e4b17023SJohn Marino 2026*e4b17023SJohn Marino /* Note: we assume argv contains at least one element; this is 2027*e4b17023SJohn Marino checked above. */ 2028*e4b17023SJohn Marino 2029*e4b17023SJohn Marino response_file = make_temp_file (""); 2030*e4b17023SJohn Marino 2031*e4b17023SJohn Marino f = fopen (response_file, "w"); 2032*e4b17023SJohn Marino 2033*e4b17023SJohn Marino if (f == NULL) 2034*e4b17023SJohn Marino fatal_error ("could not open response file %s", response_file); 2035*e4b17023SJohn Marino 2036*e4b17023SJohn Marino status = writeargv (current_argv, f); 2037*e4b17023SJohn Marino 2038*e4b17023SJohn Marino if (status) 2039*e4b17023SJohn Marino fatal_error ("could not write to response file %s", response_file); 2040*e4b17023SJohn Marino 2041*e4b17023SJohn Marino status = fclose (f); 2042*e4b17023SJohn Marino 2043*e4b17023SJohn Marino if (EOF == status) 2044*e4b17023SJohn Marino fatal_error ("could not close response file %s", response_file); 2045*e4b17023SJohn Marino 2046*e4b17023SJohn Marino response_arg = concat ("@", response_file, NULL); 2047*e4b17023SJohn Marino response_argv[0] = argv0; 2048*e4b17023SJohn Marino response_argv[1] = response_arg; 2049*e4b17023SJohn Marino response_argv[2] = NULL; 2050*e4b17023SJohn Marino 2051*e4b17023SJohn Marino argv = response_argv; 2052*e4b17023SJohn Marino } 2053*e4b17023SJohn Marino 2054*e4b17023SJohn Marino if (vflag || debug) 2055*e4b17023SJohn Marino { 2056*e4b17023SJohn Marino char **p_argv; 2057*e4b17023SJohn Marino const char *str; 2058*e4b17023SJohn Marino 2059*e4b17023SJohn Marino if (argv[0]) 2060*e4b17023SJohn Marino fprintf (stderr, "%s", argv[0]); 2061*e4b17023SJohn Marino else 2062*e4b17023SJohn Marino notice ("[cannot find %s]", prog); 2063*e4b17023SJohn Marino 2064*e4b17023SJohn Marino for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++) 2065*e4b17023SJohn Marino fprintf (stderr, " %s", str); 2066*e4b17023SJohn Marino 2067*e4b17023SJohn Marino fprintf (stderr, "\n"); 2068*e4b17023SJohn Marino } 2069*e4b17023SJohn Marino 2070*e4b17023SJohn Marino fflush (stdout); 2071*e4b17023SJohn Marino fflush (stderr); 2072*e4b17023SJohn Marino 2073*e4b17023SJohn Marino /* If we cannot find a program we need, complain error. Do this here 2074*e4b17023SJohn Marino since we might not end up needing something that we could not find. */ 2075*e4b17023SJohn Marino 2076*e4b17023SJohn Marino if (argv[0] == 0) 2077*e4b17023SJohn Marino fatal_error ("cannot find '%s'", prog); 2078*e4b17023SJohn Marino 2079*e4b17023SJohn Marino pex = pex_init (0, "collect2", NULL); 2080*e4b17023SJohn Marino if (pex == NULL) 2081*e4b17023SJohn Marino fatal_error ("pex_init failed: %m"); 2082*e4b17023SJohn Marino 2083*e4b17023SJohn Marino errmsg = pex_run (pex, flags, argv[0], argv, outname, 2084*e4b17023SJohn Marino errname, &err); 2085*e4b17023SJohn Marino if (errmsg != NULL) 2086*e4b17023SJohn Marino { 2087*e4b17023SJohn Marino if (err != 0) 2088*e4b17023SJohn Marino { 2089*e4b17023SJohn Marino errno = err; 2090*e4b17023SJohn Marino fatal_error ("%s: %m", _(errmsg)); 2091*e4b17023SJohn Marino } 2092*e4b17023SJohn Marino else 2093*e4b17023SJohn Marino fatal_error (errmsg); 2094*e4b17023SJohn Marino } 2095*e4b17023SJohn Marino 2096*e4b17023SJohn Marino free (response_arg); 2097*e4b17023SJohn Marino 2098*e4b17023SJohn Marino return pex; 2099*e4b17023SJohn Marino } 2100*e4b17023SJohn Marino 2101*e4b17023SJohn Marino static void 2102*e4b17023SJohn Marino fork_execute (const char *prog, char **argv) 2103*e4b17023SJohn Marino { 2104*e4b17023SJohn Marino struct pex_obj *pex; 2105*e4b17023SJohn Marino 2106*e4b17023SJohn Marino pex = collect_execute (prog, argv, NULL, NULL, PEX_LAST | PEX_SEARCH); 2107*e4b17023SJohn Marino do_wait (prog, pex); 2108*e4b17023SJohn Marino } 2109*e4b17023SJohn Marino 2110*e4b17023SJohn Marino /* Unlink a file unless we are debugging. */ 2111*e4b17023SJohn Marino 2112*e4b17023SJohn Marino static void 2113*e4b17023SJohn Marino maybe_unlink (const char *file) 2114*e4b17023SJohn Marino { 2115*e4b17023SJohn Marino if (!debug) 2116*e4b17023SJohn Marino unlink_if_ordinary (file); 2117*e4b17023SJohn Marino else 2118*e4b17023SJohn Marino notice ("[Leaving %s]\n", file); 2119*e4b17023SJohn Marino } 2120*e4b17023SJohn Marino 2121*e4b17023SJohn Marino /* Call maybe_unlink on the NULL-terminated list, FILE_LIST. */ 2122*e4b17023SJohn Marino 2123*e4b17023SJohn Marino static void 2124*e4b17023SJohn Marino maybe_unlink_list (char **file_list) 2125*e4b17023SJohn Marino { 2126*e4b17023SJohn Marino char **tmp = file_list; 2127*e4b17023SJohn Marino 2128*e4b17023SJohn Marino while (*tmp) 2129*e4b17023SJohn Marino maybe_unlink (*(tmp++)); 2130*e4b17023SJohn Marino } 2131*e4b17023SJohn Marino 2132*e4b17023SJohn Marino 2133*e4b17023SJohn Marino static long sequence_number = 0; 2134*e4b17023SJohn Marino 2135*e4b17023SJohn Marino /* Add a name to a linked list. */ 2136*e4b17023SJohn Marino 2137*e4b17023SJohn Marino static void 2138*e4b17023SJohn Marino add_to_list (struct head *head_ptr, const char *name) 2139*e4b17023SJohn Marino { 2140*e4b17023SJohn Marino struct id *newid 2141*e4b17023SJohn Marino = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1); 2142*e4b17023SJohn Marino struct id *p; 2143*e4b17023SJohn Marino strcpy (newid->name, name); 2144*e4b17023SJohn Marino 2145*e4b17023SJohn Marino if (head_ptr->first) 2146*e4b17023SJohn Marino head_ptr->last->next = newid; 2147*e4b17023SJohn Marino else 2148*e4b17023SJohn Marino head_ptr->first = newid; 2149*e4b17023SJohn Marino 2150*e4b17023SJohn Marino /* Check for duplicate symbols. */ 2151*e4b17023SJohn Marino for (p = head_ptr->first; 2152*e4b17023SJohn Marino strcmp (name, p->name) != 0; 2153*e4b17023SJohn Marino p = p->next) 2154*e4b17023SJohn Marino ; 2155*e4b17023SJohn Marino if (p != newid) 2156*e4b17023SJohn Marino { 2157*e4b17023SJohn Marino head_ptr->last->next = 0; 2158*e4b17023SJohn Marino free (newid); 2159*e4b17023SJohn Marino return; 2160*e4b17023SJohn Marino } 2161*e4b17023SJohn Marino 2162*e4b17023SJohn Marino newid->sequence = ++sequence_number; 2163*e4b17023SJohn Marino head_ptr->last = newid; 2164*e4b17023SJohn Marino head_ptr->number++; 2165*e4b17023SJohn Marino } 2166*e4b17023SJohn Marino 2167*e4b17023SJohn Marino /* Grab the init priority number from an init function name that 2168*e4b17023SJohn Marino looks like "_GLOBAL_.I.12345.foo". */ 2169*e4b17023SJohn Marino 2170*e4b17023SJohn Marino static int 2171*e4b17023SJohn Marino extract_init_priority (const char *name) 2172*e4b17023SJohn Marino { 2173*e4b17023SJohn Marino int pos = 0, pri; 2174*e4b17023SJohn Marino 2175*e4b17023SJohn Marino while (name[pos] == '_') 2176*e4b17023SJohn Marino ++pos; 2177*e4b17023SJohn Marino pos += 10; /* strlen ("GLOBAL__X_") */ 2178*e4b17023SJohn Marino 2179*e4b17023SJohn Marino /* Extract init_p number from ctor/dtor name. */ 2180*e4b17023SJohn Marino pri = atoi (name + pos); 2181*e4b17023SJohn Marino return pri ? pri : DEFAULT_INIT_PRIORITY; 2182*e4b17023SJohn Marino } 2183*e4b17023SJohn Marino 2184*e4b17023SJohn Marino /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order. 2185*e4b17023SJohn Marino ctors will be run from right to left, dtors from left to right. */ 2186*e4b17023SJohn Marino 2187*e4b17023SJohn Marino static void 2188*e4b17023SJohn Marino sort_ids (struct head *head_ptr) 2189*e4b17023SJohn Marino { 2190*e4b17023SJohn Marino /* id holds the current element to insert. id_next holds the next 2191*e4b17023SJohn Marino element to insert. id_ptr iterates through the already sorted elements 2192*e4b17023SJohn Marino looking for the place to insert id. */ 2193*e4b17023SJohn Marino struct id *id, *id_next, **id_ptr; 2194*e4b17023SJohn Marino 2195*e4b17023SJohn Marino id = head_ptr->first; 2196*e4b17023SJohn Marino 2197*e4b17023SJohn Marino /* We don't have any sorted elements yet. */ 2198*e4b17023SJohn Marino head_ptr->first = NULL; 2199*e4b17023SJohn Marino 2200*e4b17023SJohn Marino for (; id; id = id_next) 2201*e4b17023SJohn Marino { 2202*e4b17023SJohn Marino id_next = id->next; 2203*e4b17023SJohn Marino id->sequence = extract_init_priority (id->name); 2204*e4b17023SJohn Marino 2205*e4b17023SJohn Marino for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next)) 2206*e4b17023SJohn Marino if (*id_ptr == NULL 2207*e4b17023SJohn Marino /* If the sequence numbers are the same, we put the id from the 2208*e4b17023SJohn Marino file later on the command line later in the list. */ 2209*e4b17023SJohn Marino || id->sequence > (*id_ptr)->sequence 2210*e4b17023SJohn Marino /* Hack: do lexical compare, too. 2211*e4b17023SJohn Marino || (id->sequence == (*id_ptr)->sequence 2212*e4b17023SJohn Marino && strcmp (id->name, (*id_ptr)->name) > 0) */ 2213*e4b17023SJohn Marino ) 2214*e4b17023SJohn Marino { 2215*e4b17023SJohn Marino id->next = *id_ptr; 2216*e4b17023SJohn Marino *id_ptr = id; 2217*e4b17023SJohn Marino break; 2218*e4b17023SJohn Marino } 2219*e4b17023SJohn Marino } 2220*e4b17023SJohn Marino 2221*e4b17023SJohn Marino /* Now set the sequence numbers properly so write_c_file works. */ 2222*e4b17023SJohn Marino for (id = head_ptr->first; id; id = id->next) 2223*e4b17023SJohn Marino id->sequence = ++sequence_number; 2224*e4b17023SJohn Marino } 2225*e4b17023SJohn Marino 2226*e4b17023SJohn Marino /* Write: `prefix', the names on list LIST, `suffix'. */ 2227*e4b17023SJohn Marino 2228*e4b17023SJohn Marino static void 2229*e4b17023SJohn Marino write_list (FILE *stream, const char *prefix, struct id *list) 2230*e4b17023SJohn Marino { 2231*e4b17023SJohn Marino while (list) 2232*e4b17023SJohn Marino { 2233*e4b17023SJohn Marino fprintf (stream, "%sx%d,\n", prefix, list->sequence); 2234*e4b17023SJohn Marino list = list->next; 2235*e4b17023SJohn Marino } 2236*e4b17023SJohn Marino } 2237*e4b17023SJohn Marino 2238*e4b17023SJohn Marino #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES 2239*e4b17023SJohn Marino /* Given a STRING, return nonzero if it occurs in the list in range 2240*e4b17023SJohn Marino [ARGS_BEGIN,ARGS_END). */ 2241*e4b17023SJohn Marino 2242*e4b17023SJohn Marino static int 2243*e4b17023SJohn Marino is_in_args (const char *string, const char **args_begin, 2244*e4b17023SJohn Marino const char **args_end) 2245*e4b17023SJohn Marino { 2246*e4b17023SJohn Marino const char **args_pointer; 2247*e4b17023SJohn Marino for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer) 2248*e4b17023SJohn Marino if (strcmp (string, *args_pointer) == 0) 2249*e4b17023SJohn Marino return 1; 2250*e4b17023SJohn Marino return 0; 2251*e4b17023SJohn Marino } 2252*e4b17023SJohn Marino #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */ 2253*e4b17023SJohn Marino 2254*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 2255*e4b17023SJohn Marino /* This function is really used only on AIX, but may be useful. */ 2256*e4b17023SJohn Marino #if 0 2257*e4b17023SJohn Marino static int 2258*e4b17023SJohn Marino is_in_list (const char *prefix, struct id *list) 2259*e4b17023SJohn Marino { 2260*e4b17023SJohn Marino while (list) 2261*e4b17023SJohn Marino { 2262*e4b17023SJohn Marino if (!strcmp (prefix, list->name)) return 1; 2263*e4b17023SJohn Marino list = list->next; 2264*e4b17023SJohn Marino } 2265*e4b17023SJohn Marino return 0; 2266*e4b17023SJohn Marino } 2267*e4b17023SJohn Marino #endif 2268*e4b17023SJohn Marino #endif /* COLLECT_EXPORT_LIST */ 2269*e4b17023SJohn Marino 2270*e4b17023SJohn Marino /* Added for debugging purpose. */ 2271*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 2272*e4b17023SJohn Marino static void 2273*e4b17023SJohn Marino dump_list (FILE *stream, const char *prefix, struct id *list) 2274*e4b17023SJohn Marino { 2275*e4b17023SJohn Marino while (list) 2276*e4b17023SJohn Marino { 2277*e4b17023SJohn Marino fprintf (stream, "%s%s,\n", prefix, list->name); 2278*e4b17023SJohn Marino list = list->next; 2279*e4b17023SJohn Marino } 2280*e4b17023SJohn Marino } 2281*e4b17023SJohn Marino #endif 2282*e4b17023SJohn Marino 2283*e4b17023SJohn Marino #if 0 2284*e4b17023SJohn Marino static void 2285*e4b17023SJohn Marino dump_prefix_list (FILE *stream, const char *prefix, struct prefix_list *list) 2286*e4b17023SJohn Marino { 2287*e4b17023SJohn Marino while (list) 2288*e4b17023SJohn Marino { 2289*e4b17023SJohn Marino fprintf (stream, "%s%s,\n", prefix, list->prefix); 2290*e4b17023SJohn Marino list = list->next; 2291*e4b17023SJohn Marino } 2292*e4b17023SJohn Marino } 2293*e4b17023SJohn Marino #endif 2294*e4b17023SJohn Marino 2295*e4b17023SJohn Marino static void 2296*e4b17023SJohn Marino write_list_with_asm (FILE *stream, const char *prefix, struct id *list) 2297*e4b17023SJohn Marino { 2298*e4b17023SJohn Marino while (list) 2299*e4b17023SJohn Marino { 2300*e4b17023SJohn Marino fprintf (stream, "%sx%d __asm__ (\"%s\");\n", 2301*e4b17023SJohn Marino prefix, list->sequence, list->name); 2302*e4b17023SJohn Marino list = list->next; 2303*e4b17023SJohn Marino } 2304*e4b17023SJohn Marino } 2305*e4b17023SJohn Marino 2306*e4b17023SJohn Marino /* Write out the constructor and destructor tables statically (for a shared 2307*e4b17023SJohn Marino object), along with the functions to execute them. */ 2308*e4b17023SJohn Marino 2309*e4b17023SJohn Marino static void 2310*e4b17023SJohn Marino write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED) 2311*e4b17023SJohn Marino { 2312*e4b17023SJohn Marino const char *p, *q; 2313*e4b17023SJohn Marino char *prefix, *r; 2314*e4b17023SJohn Marino int frames = (frame_tables.number > 0); 2315*e4b17023SJohn Marino 2316*e4b17023SJohn Marino /* Figure out name of output_file, stripping off .so version. */ 2317*e4b17023SJohn Marino q = p = lbasename (output_file); 2318*e4b17023SJohn Marino 2319*e4b17023SJohn Marino while (q) 2320*e4b17023SJohn Marino { 2321*e4b17023SJohn Marino q = strchr (q,'.'); 2322*e4b17023SJohn Marino if (q == 0) 2323*e4b17023SJohn Marino { 2324*e4b17023SJohn Marino q = p + strlen (p); 2325*e4b17023SJohn Marino break; 2326*e4b17023SJohn Marino } 2327*e4b17023SJohn Marino else 2328*e4b17023SJohn Marino { 2329*e4b17023SJohn Marino if (filename_ncmp (q, SHLIB_SUFFIX, strlen (SHLIB_SUFFIX)) == 0) 2330*e4b17023SJohn Marino { 2331*e4b17023SJohn Marino q += strlen (SHLIB_SUFFIX); 2332*e4b17023SJohn Marino break; 2333*e4b17023SJohn Marino } 2334*e4b17023SJohn Marino else 2335*e4b17023SJohn Marino q++; 2336*e4b17023SJohn Marino } 2337*e4b17023SJohn Marino } 2338*e4b17023SJohn Marino /* q points to null at end of the string (or . of the .so version) */ 2339*e4b17023SJohn Marino prefix = XNEWVEC (char, q - p + 1); 2340*e4b17023SJohn Marino strncpy (prefix, p, q - p); 2341*e4b17023SJohn Marino prefix[q - p] = 0; 2342*e4b17023SJohn Marino for (r = prefix; *r; r++) 2343*e4b17023SJohn Marino if (!ISALNUM ((unsigned char)*r)) 2344*e4b17023SJohn Marino *r = '_'; 2345*e4b17023SJohn Marino if (debug) 2346*e4b17023SJohn Marino notice ("\nwrite_c_file - output name is %s, prefix is %s\n", 2347*e4b17023SJohn Marino output_file, prefix); 2348*e4b17023SJohn Marino 2349*e4b17023SJohn Marino initname = concat ("_GLOBAL__FI_", prefix, NULL); 2350*e4b17023SJohn Marino fininame = concat ("_GLOBAL__FD_", prefix, NULL); 2351*e4b17023SJohn Marino 2352*e4b17023SJohn Marino free (prefix); 2353*e4b17023SJohn Marino 2354*e4b17023SJohn Marino /* Write the tables as C code. */ 2355*e4b17023SJohn Marino 2356*e4b17023SJohn Marino fprintf (stream, "static int count;\n"); 2357*e4b17023SJohn Marino fprintf (stream, "typedef void entry_pt();\n"); 2358*e4b17023SJohn Marino write_list_with_asm (stream, "extern entry_pt ", constructors.first); 2359*e4b17023SJohn Marino 2360*e4b17023SJohn Marino if (frames) 2361*e4b17023SJohn Marino { 2362*e4b17023SJohn Marino write_list_with_asm (stream, "extern void *", frame_tables.first); 2363*e4b17023SJohn Marino 2364*e4b17023SJohn Marino fprintf (stream, "\tstatic void *frame_table[] = {\n"); 2365*e4b17023SJohn Marino write_list (stream, "\t\t&", frame_tables.first); 2366*e4b17023SJohn Marino fprintf (stream, "\t0\n};\n"); 2367*e4b17023SJohn Marino 2368*e4b17023SJohn Marino /* This must match what's in frame.h. */ 2369*e4b17023SJohn Marino fprintf (stream, "struct object {\n"); 2370*e4b17023SJohn Marino fprintf (stream, " void *pc_begin;\n"); 2371*e4b17023SJohn Marino fprintf (stream, " void *pc_end;\n"); 2372*e4b17023SJohn Marino fprintf (stream, " void *fde_begin;\n"); 2373*e4b17023SJohn Marino fprintf (stream, " void *fde_array;\n"); 2374*e4b17023SJohn Marino fprintf (stream, " __SIZE_TYPE__ count;\n"); 2375*e4b17023SJohn Marino fprintf (stream, " struct object *next;\n"); 2376*e4b17023SJohn Marino fprintf (stream, "};\n"); 2377*e4b17023SJohn Marino 2378*e4b17023SJohn Marino fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n"); 2379*e4b17023SJohn Marino fprintf (stream, "extern void *__deregister_frame_info (void *);\n"); 2380*e4b17023SJohn Marino 2381*e4b17023SJohn Marino fprintf (stream, "static void reg_frame () {\n"); 2382*e4b17023SJohn Marino fprintf (stream, "\tstatic struct object ob;\n"); 2383*e4b17023SJohn Marino fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n"); 2384*e4b17023SJohn Marino fprintf (stream, "\t}\n"); 2385*e4b17023SJohn Marino 2386*e4b17023SJohn Marino fprintf (stream, "static void dereg_frame () {\n"); 2387*e4b17023SJohn Marino fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); 2388*e4b17023SJohn Marino fprintf (stream, "\t}\n"); 2389*e4b17023SJohn Marino } 2390*e4b17023SJohn Marino 2391*e4b17023SJohn Marino fprintf (stream, "void %s() {\n", initname); 2392*e4b17023SJohn Marino if (constructors.number > 0 || frames) 2393*e4b17023SJohn Marino { 2394*e4b17023SJohn Marino fprintf (stream, "\tstatic entry_pt *ctors[] = {\n"); 2395*e4b17023SJohn Marino write_list (stream, "\t\t", constructors.first); 2396*e4b17023SJohn Marino if (frames) 2397*e4b17023SJohn Marino fprintf (stream, "\treg_frame,\n"); 2398*e4b17023SJohn Marino fprintf (stream, "\t};\n"); 2399*e4b17023SJohn Marino fprintf (stream, "\tentry_pt **p;\n"); 2400*e4b17023SJohn Marino fprintf (stream, "\tif (count++ != 0) return;\n"); 2401*e4b17023SJohn Marino fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames); 2402*e4b17023SJohn Marino fprintf (stream, "\twhile (p > ctors) (*--p)();\n"); 2403*e4b17023SJohn Marino } 2404*e4b17023SJohn Marino else 2405*e4b17023SJohn Marino fprintf (stream, "\t++count;\n"); 2406*e4b17023SJohn Marino fprintf (stream, "}\n"); 2407*e4b17023SJohn Marino write_list_with_asm (stream, "extern entry_pt ", destructors.first); 2408*e4b17023SJohn Marino fprintf (stream, "void %s() {\n", fininame); 2409*e4b17023SJohn Marino if (destructors.number > 0 || frames) 2410*e4b17023SJohn Marino { 2411*e4b17023SJohn Marino fprintf (stream, "\tstatic entry_pt *dtors[] = {\n"); 2412*e4b17023SJohn Marino write_list (stream, "\t\t", destructors.first); 2413*e4b17023SJohn Marino if (frames) 2414*e4b17023SJohn Marino fprintf (stream, "\tdereg_frame,\n"); 2415*e4b17023SJohn Marino fprintf (stream, "\t};\n"); 2416*e4b17023SJohn Marino fprintf (stream, "\tentry_pt **p;\n"); 2417*e4b17023SJohn Marino fprintf (stream, "\tif (--count != 0) return;\n"); 2418*e4b17023SJohn Marino fprintf (stream, "\tp = dtors;\n"); 2419*e4b17023SJohn Marino fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n", 2420*e4b17023SJohn Marino destructors.number + frames); 2421*e4b17023SJohn Marino } 2422*e4b17023SJohn Marino fprintf (stream, "}\n"); 2423*e4b17023SJohn Marino 2424*e4b17023SJohn Marino if (shared_obj) 2425*e4b17023SJohn Marino { 2426*e4b17023SJohn Marino COLLECT_SHARED_INIT_FUNC(stream, initname); 2427*e4b17023SJohn Marino COLLECT_SHARED_FINI_FUNC(stream, fininame); 2428*e4b17023SJohn Marino } 2429*e4b17023SJohn Marino } 2430*e4b17023SJohn Marino 2431*e4b17023SJohn Marino /* Write the constructor/destructor tables. */ 2432*e4b17023SJohn Marino 2433*e4b17023SJohn Marino #ifndef LD_INIT_SWITCH 2434*e4b17023SJohn Marino static void 2435*e4b17023SJohn Marino write_c_file_glob (FILE *stream, const char *name ATTRIBUTE_UNUSED) 2436*e4b17023SJohn Marino { 2437*e4b17023SJohn Marino /* Write the tables as C code. */ 2438*e4b17023SJohn Marino 2439*e4b17023SJohn Marino int frames = (frame_tables.number > 0); 2440*e4b17023SJohn Marino 2441*e4b17023SJohn Marino fprintf (stream, "typedef void entry_pt();\n\n"); 2442*e4b17023SJohn Marino 2443*e4b17023SJohn Marino write_list_with_asm (stream, "extern entry_pt ", constructors.first); 2444*e4b17023SJohn Marino 2445*e4b17023SJohn Marino if (frames) 2446*e4b17023SJohn Marino { 2447*e4b17023SJohn Marino write_list_with_asm (stream, "extern void *", frame_tables.first); 2448*e4b17023SJohn Marino 2449*e4b17023SJohn Marino fprintf (stream, "\tstatic void *frame_table[] = {\n"); 2450*e4b17023SJohn Marino write_list (stream, "\t\t&", frame_tables.first); 2451*e4b17023SJohn Marino fprintf (stream, "\t0\n};\n"); 2452*e4b17023SJohn Marino 2453*e4b17023SJohn Marino /* This must match what's in frame.h. */ 2454*e4b17023SJohn Marino fprintf (stream, "struct object {\n"); 2455*e4b17023SJohn Marino fprintf (stream, " void *pc_begin;\n"); 2456*e4b17023SJohn Marino fprintf (stream, " void *pc_end;\n"); 2457*e4b17023SJohn Marino fprintf (stream, " void *fde_begin;\n"); 2458*e4b17023SJohn Marino fprintf (stream, " void *fde_array;\n"); 2459*e4b17023SJohn Marino fprintf (stream, " __SIZE_TYPE__ count;\n"); 2460*e4b17023SJohn Marino fprintf (stream, " struct object *next;\n"); 2461*e4b17023SJohn Marino fprintf (stream, "};\n"); 2462*e4b17023SJohn Marino 2463*e4b17023SJohn Marino fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n"); 2464*e4b17023SJohn Marino fprintf (stream, "extern void *__deregister_frame_info (void *);\n"); 2465*e4b17023SJohn Marino 2466*e4b17023SJohn Marino fprintf (stream, "static void reg_frame () {\n"); 2467*e4b17023SJohn Marino fprintf (stream, "\tstatic struct object ob;\n"); 2468*e4b17023SJohn Marino fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n"); 2469*e4b17023SJohn Marino fprintf (stream, "\t}\n"); 2470*e4b17023SJohn Marino 2471*e4b17023SJohn Marino fprintf (stream, "static void dereg_frame () {\n"); 2472*e4b17023SJohn Marino fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); 2473*e4b17023SJohn Marino fprintf (stream, "\t}\n"); 2474*e4b17023SJohn Marino } 2475*e4b17023SJohn Marino 2476*e4b17023SJohn Marino fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n"); 2477*e4b17023SJohn Marino fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames); 2478*e4b17023SJohn Marino write_list (stream, "\t", constructors.first); 2479*e4b17023SJohn Marino if (frames) 2480*e4b17023SJohn Marino fprintf (stream, "\treg_frame,\n"); 2481*e4b17023SJohn Marino fprintf (stream, "\t0\n};\n\n"); 2482*e4b17023SJohn Marino 2483*e4b17023SJohn Marino write_list_with_asm (stream, "extern entry_pt ", destructors.first); 2484*e4b17023SJohn Marino 2485*e4b17023SJohn Marino fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n"); 2486*e4b17023SJohn Marino fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames); 2487*e4b17023SJohn Marino write_list (stream, "\t", destructors.first); 2488*e4b17023SJohn Marino if (frames) 2489*e4b17023SJohn Marino fprintf (stream, "\tdereg_frame,\n"); 2490*e4b17023SJohn Marino fprintf (stream, "\t0\n};\n\n"); 2491*e4b17023SJohn Marino 2492*e4b17023SJohn Marino fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN); 2493*e4b17023SJohn Marino fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN); 2494*e4b17023SJohn Marino } 2495*e4b17023SJohn Marino #endif /* ! LD_INIT_SWITCH */ 2496*e4b17023SJohn Marino 2497*e4b17023SJohn Marino static void 2498*e4b17023SJohn Marino write_c_file (FILE *stream, const char *name) 2499*e4b17023SJohn Marino { 2500*e4b17023SJohn Marino #ifndef LD_INIT_SWITCH 2501*e4b17023SJohn Marino if (! shared_obj) 2502*e4b17023SJohn Marino write_c_file_glob (stream, name); 2503*e4b17023SJohn Marino else 2504*e4b17023SJohn Marino #endif 2505*e4b17023SJohn Marino write_c_file_stat (stream, name); 2506*e4b17023SJohn Marino } 2507*e4b17023SJohn Marino 2508*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 2509*e4b17023SJohn Marino static void 2510*e4b17023SJohn Marino write_aix_file (FILE *stream, struct id *list) 2511*e4b17023SJohn Marino { 2512*e4b17023SJohn Marino for (; list; list = list->next) 2513*e4b17023SJohn Marino { 2514*e4b17023SJohn Marino fputs (list->name, stream); 2515*e4b17023SJohn Marino putc ('\n', stream); 2516*e4b17023SJohn Marino } 2517*e4b17023SJohn Marino } 2518*e4b17023SJohn Marino #endif 2519*e4b17023SJohn Marino 2520*e4b17023SJohn Marino #ifdef OBJECT_FORMAT_NONE 2521*e4b17023SJohn Marino 2522*e4b17023SJohn Marino /* Check to make sure the file is an LTO object file. */ 2523*e4b17023SJohn Marino 2524*e4b17023SJohn Marino static bool 2525*e4b17023SJohn Marino maybe_lto_object_file (const char *prog_name) 2526*e4b17023SJohn Marino { 2527*e4b17023SJohn Marino FILE *f; 2528*e4b17023SJohn Marino unsigned char buf[4]; 2529*e4b17023SJohn Marino int i; 2530*e4b17023SJohn Marino 2531*e4b17023SJohn Marino static unsigned char elfmagic[4] = { 0x7f, 'E', 'L', 'F' }; 2532*e4b17023SJohn Marino static unsigned char coffmagic[2] = { 0x4c, 0x01 }; 2533*e4b17023SJohn Marino static unsigned char coffmagic_x64[2] = { 0x64, 0x86 }; 2534*e4b17023SJohn Marino static unsigned char machomagic[4][4] = { 2535*e4b17023SJohn Marino { 0xcf, 0xfa, 0xed, 0xfe }, 2536*e4b17023SJohn Marino { 0xce, 0xfa, 0xed, 0xfe }, 2537*e4b17023SJohn Marino { 0xfe, 0xed, 0xfa, 0xcf }, 2538*e4b17023SJohn Marino { 0xfe, 0xed, 0xfa, 0xce } 2539*e4b17023SJohn Marino }; 2540*e4b17023SJohn Marino 2541*e4b17023SJohn Marino f = fopen (prog_name, "rb"); 2542*e4b17023SJohn Marino if (f == NULL) 2543*e4b17023SJohn Marino return false; 2544*e4b17023SJohn Marino if (fread (buf, sizeof (buf), 1, f) != 1) 2545*e4b17023SJohn Marino buf[0] = 0; 2546*e4b17023SJohn Marino fclose (f); 2547*e4b17023SJohn Marino 2548*e4b17023SJohn Marino if (memcmp (buf, elfmagic, sizeof (elfmagic)) == 0 2549*e4b17023SJohn Marino || memcmp (buf, coffmagic, sizeof (coffmagic)) == 0 2550*e4b17023SJohn Marino || memcmp (buf, coffmagic_x64, sizeof (coffmagic_x64)) == 0) 2551*e4b17023SJohn Marino return true; 2552*e4b17023SJohn Marino for (i = 0; i < 4; i++) 2553*e4b17023SJohn Marino if (memcmp (buf, machomagic[i], sizeof (machomagic[i])) == 0) 2554*e4b17023SJohn Marino return true; 2555*e4b17023SJohn Marino 2556*e4b17023SJohn Marino return false; 2557*e4b17023SJohn Marino } 2558*e4b17023SJohn Marino 2559*e4b17023SJohn Marino /* Generic version to scan the name list of the loaded program for 2560*e4b17023SJohn Marino the symbols g++ uses for static constructors and destructors. */ 2561*e4b17023SJohn Marino 2562*e4b17023SJohn Marino static void 2563*e4b17023SJohn Marino scan_prog_file (const char *prog_name, scanpass which_pass, 2564*e4b17023SJohn Marino scanfilter filter) 2565*e4b17023SJohn Marino { 2566*e4b17023SJohn Marino void (*int_handler) (int); 2567*e4b17023SJohn Marino #ifdef SIGQUIT 2568*e4b17023SJohn Marino void (*quit_handler) (int); 2569*e4b17023SJohn Marino #endif 2570*e4b17023SJohn Marino char *real_nm_argv[4]; 2571*e4b17023SJohn Marino const char **nm_argv = CONST_CAST2 (const char **, char**, real_nm_argv); 2572*e4b17023SJohn Marino int argc = 0; 2573*e4b17023SJohn Marino struct pex_obj *pex; 2574*e4b17023SJohn Marino const char *errmsg; 2575*e4b17023SJohn Marino int err; 2576*e4b17023SJohn Marino char *p, buf[1024]; 2577*e4b17023SJohn Marino FILE *inf; 2578*e4b17023SJohn Marino int found_lto = 0; 2579*e4b17023SJohn Marino 2580*e4b17023SJohn Marino if (which_pass == PASS_SECOND) 2581*e4b17023SJohn Marino return; 2582*e4b17023SJohn Marino 2583*e4b17023SJohn Marino /* LTO objects must be in a known format. This check prevents 2584*e4b17023SJohn Marino us from accepting an archive containing LTO objects, which 2585*e4b17023SJohn Marino gcc cannnot currently handle. */ 2586*e4b17023SJohn Marino if (which_pass == PASS_LTOINFO && !maybe_lto_object_file (prog_name)) 2587*e4b17023SJohn Marino return; 2588*e4b17023SJohn Marino 2589*e4b17023SJohn Marino /* If we do not have an `nm', complain. */ 2590*e4b17023SJohn Marino if (nm_file_name == 0) 2591*e4b17023SJohn Marino fatal_error ("cannot find 'nm'"); 2592*e4b17023SJohn Marino 2593*e4b17023SJohn Marino nm_argv[argc++] = nm_file_name; 2594*e4b17023SJohn Marino if (NM_FLAGS[0] != '\0') 2595*e4b17023SJohn Marino nm_argv[argc++] = NM_FLAGS; 2596*e4b17023SJohn Marino 2597*e4b17023SJohn Marino nm_argv[argc++] = prog_name; 2598*e4b17023SJohn Marino nm_argv[argc++] = (char *) 0; 2599*e4b17023SJohn Marino 2600*e4b17023SJohn Marino /* Trace if needed. */ 2601*e4b17023SJohn Marino if (vflag) 2602*e4b17023SJohn Marino { 2603*e4b17023SJohn Marino const char **p_argv; 2604*e4b17023SJohn Marino const char *str; 2605*e4b17023SJohn Marino 2606*e4b17023SJohn Marino for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++) 2607*e4b17023SJohn Marino fprintf (stderr, " %s", str); 2608*e4b17023SJohn Marino 2609*e4b17023SJohn Marino fprintf (stderr, "\n"); 2610*e4b17023SJohn Marino } 2611*e4b17023SJohn Marino 2612*e4b17023SJohn Marino fflush (stdout); 2613*e4b17023SJohn Marino fflush (stderr); 2614*e4b17023SJohn Marino 2615*e4b17023SJohn Marino pex = pex_init (PEX_USE_PIPES, "collect2", NULL); 2616*e4b17023SJohn Marino if (pex == NULL) 2617*e4b17023SJohn Marino fatal_error ("pex_init failed: %m"); 2618*e4b17023SJohn Marino 2619*e4b17023SJohn Marino errmsg = pex_run (pex, 0, nm_file_name, real_nm_argv, NULL, HOST_BIT_BUCKET, 2620*e4b17023SJohn Marino &err); 2621*e4b17023SJohn Marino if (errmsg != NULL) 2622*e4b17023SJohn Marino { 2623*e4b17023SJohn Marino if (err != 0) 2624*e4b17023SJohn Marino { 2625*e4b17023SJohn Marino errno = err; 2626*e4b17023SJohn Marino fatal_error ("%s: %m", _(errmsg)); 2627*e4b17023SJohn Marino } 2628*e4b17023SJohn Marino else 2629*e4b17023SJohn Marino fatal_error (errmsg); 2630*e4b17023SJohn Marino } 2631*e4b17023SJohn Marino 2632*e4b17023SJohn Marino int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN); 2633*e4b17023SJohn Marino #ifdef SIGQUIT 2634*e4b17023SJohn Marino quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN); 2635*e4b17023SJohn Marino #endif 2636*e4b17023SJohn Marino 2637*e4b17023SJohn Marino inf = pex_read_output (pex, 0); 2638*e4b17023SJohn Marino if (inf == NULL) 2639*e4b17023SJohn Marino fatal_error ("can't open nm output: %m"); 2640*e4b17023SJohn Marino 2641*e4b17023SJohn Marino if (debug) 2642*e4b17023SJohn Marino { 2643*e4b17023SJohn Marino if (which_pass == PASS_LTOINFO) 2644*e4b17023SJohn Marino fprintf (stderr, "\nnm output with LTO info marker symbol.\n"); 2645*e4b17023SJohn Marino else 2646*e4b17023SJohn Marino fprintf (stderr, "\nnm output with constructors/destructors.\n"); 2647*e4b17023SJohn Marino } 2648*e4b17023SJohn Marino 2649*e4b17023SJohn Marino /* Read each line of nm output. */ 2650*e4b17023SJohn Marino while (fgets (buf, sizeof buf, inf) != (char *) 0) 2651*e4b17023SJohn Marino { 2652*e4b17023SJohn Marino int ch, ch2; 2653*e4b17023SJohn Marino char *name, *end; 2654*e4b17023SJohn Marino 2655*e4b17023SJohn Marino if (debug) 2656*e4b17023SJohn Marino fprintf (stderr, "\t%s\n", buf); 2657*e4b17023SJohn Marino 2658*e4b17023SJohn Marino if (which_pass == PASS_LTOINFO) 2659*e4b17023SJohn Marino { 2660*e4b17023SJohn Marino if (found_lto) 2661*e4b17023SJohn Marino continue; 2662*e4b17023SJohn Marino 2663*e4b17023SJohn Marino /* Look for the LTO info marker symbol, and add filename to 2664*e4b17023SJohn Marino the LTO objects list if found. */ 2665*e4b17023SJohn Marino for (p = buf; (ch = *p) != '\0' && ch != '\n'; p++) 2666*e4b17023SJohn Marino if (ch == ' ' && p[1] == '_' && p[2] == '_' 2667*e4b17023SJohn Marino && (strncmp (p + (p[3] == '_' ? 2 : 1), "__gnu_lto_v1", 12) == 0) 2668*e4b17023SJohn Marino && ISSPACE (p[p[3] == '_' ? 14 : 13])) 2669*e4b17023SJohn Marino { 2670*e4b17023SJohn Marino add_lto_object (<o_objects, prog_name); 2671*e4b17023SJohn Marino 2672*e4b17023SJohn Marino /* We need to read all the input, so we can't just 2673*e4b17023SJohn Marino return here. But we can avoid useless work. */ 2674*e4b17023SJohn Marino found_lto = 1; 2675*e4b17023SJohn Marino 2676*e4b17023SJohn Marino break; 2677*e4b17023SJohn Marino } 2678*e4b17023SJohn Marino 2679*e4b17023SJohn Marino continue; 2680*e4b17023SJohn Marino } 2681*e4b17023SJohn Marino 2682*e4b17023SJohn Marino /* If it contains a constructor or destructor name, add the name 2683*e4b17023SJohn Marino to the appropriate list unless this is a kind of symbol we're 2684*e4b17023SJohn Marino not supposed to even consider. */ 2685*e4b17023SJohn Marino 2686*e4b17023SJohn Marino for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++) 2687*e4b17023SJohn Marino if (ch == ' ' && p[1] == 'U' && p[2] == ' ') 2688*e4b17023SJohn Marino break; 2689*e4b17023SJohn Marino 2690*e4b17023SJohn Marino if (ch != '_') 2691*e4b17023SJohn Marino continue; 2692*e4b17023SJohn Marino 2693*e4b17023SJohn Marino name = p; 2694*e4b17023SJohn Marino /* Find the end of the symbol name. 2695*e4b17023SJohn Marino Do not include `|', because Encore nm can tack that on the end. */ 2696*e4b17023SJohn Marino for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|'; 2697*e4b17023SJohn Marino end++) 2698*e4b17023SJohn Marino continue; 2699*e4b17023SJohn Marino 2700*e4b17023SJohn Marino 2701*e4b17023SJohn Marino *end = '\0'; 2702*e4b17023SJohn Marino switch (is_ctor_dtor (name)) 2703*e4b17023SJohn Marino { 2704*e4b17023SJohn Marino case SYM_CTOR: 2705*e4b17023SJohn Marino if (! (filter & SCAN_CTOR)) 2706*e4b17023SJohn Marino break; 2707*e4b17023SJohn Marino if (which_pass != PASS_LIB) 2708*e4b17023SJohn Marino add_to_list (&constructors, name); 2709*e4b17023SJohn Marino break; 2710*e4b17023SJohn Marino 2711*e4b17023SJohn Marino case SYM_DTOR: 2712*e4b17023SJohn Marino if (! (filter & SCAN_DTOR)) 2713*e4b17023SJohn Marino break; 2714*e4b17023SJohn Marino if (which_pass != PASS_LIB) 2715*e4b17023SJohn Marino add_to_list (&destructors, name); 2716*e4b17023SJohn Marino break; 2717*e4b17023SJohn Marino 2718*e4b17023SJohn Marino case SYM_INIT: 2719*e4b17023SJohn Marino if (! (filter & SCAN_INIT)) 2720*e4b17023SJohn Marino break; 2721*e4b17023SJohn Marino if (which_pass != PASS_LIB) 2722*e4b17023SJohn Marino fatal_error ("init function found in object %s", prog_name); 2723*e4b17023SJohn Marino #ifndef LD_INIT_SWITCH 2724*e4b17023SJohn Marino add_to_list (&constructors, name); 2725*e4b17023SJohn Marino #endif 2726*e4b17023SJohn Marino break; 2727*e4b17023SJohn Marino 2728*e4b17023SJohn Marino case SYM_FINI: 2729*e4b17023SJohn Marino if (! (filter & SCAN_FINI)) 2730*e4b17023SJohn Marino break; 2731*e4b17023SJohn Marino if (which_pass != PASS_LIB) 2732*e4b17023SJohn Marino fatal_error ("fini function found in object %s", prog_name); 2733*e4b17023SJohn Marino #ifndef LD_FINI_SWITCH 2734*e4b17023SJohn Marino add_to_list (&destructors, name); 2735*e4b17023SJohn Marino #endif 2736*e4b17023SJohn Marino break; 2737*e4b17023SJohn Marino 2738*e4b17023SJohn Marino case SYM_DWEH: 2739*e4b17023SJohn Marino if (! (filter & SCAN_DWEH)) 2740*e4b17023SJohn Marino break; 2741*e4b17023SJohn Marino if (which_pass != PASS_LIB) 2742*e4b17023SJohn Marino add_to_list (&frame_tables, name); 2743*e4b17023SJohn Marino break; 2744*e4b17023SJohn Marino 2745*e4b17023SJohn Marino default: /* not a constructor or destructor */ 2746*e4b17023SJohn Marino continue; 2747*e4b17023SJohn Marino } 2748*e4b17023SJohn Marino } 2749*e4b17023SJohn Marino 2750*e4b17023SJohn Marino if (debug) 2751*e4b17023SJohn Marino fprintf (stderr, "\n"); 2752*e4b17023SJohn Marino 2753*e4b17023SJohn Marino do_wait (nm_file_name, pex); 2754*e4b17023SJohn Marino 2755*e4b17023SJohn Marino signal (SIGINT, int_handler); 2756*e4b17023SJohn Marino #ifdef SIGQUIT 2757*e4b17023SJohn Marino signal (SIGQUIT, quit_handler); 2758*e4b17023SJohn Marino #endif 2759*e4b17023SJohn Marino } 2760*e4b17023SJohn Marino 2761*e4b17023SJohn Marino #ifdef LDD_SUFFIX 2762*e4b17023SJohn Marino 2763*e4b17023SJohn Marino /* Use the List Dynamic Dependencies program to find shared libraries that 2764*e4b17023SJohn Marino the output file depends upon and their initialization/finalization 2765*e4b17023SJohn Marino routines, if any. */ 2766*e4b17023SJohn Marino 2767*e4b17023SJohn Marino static void 2768*e4b17023SJohn Marino scan_libraries (const char *prog_name) 2769*e4b17023SJohn Marino { 2770*e4b17023SJohn Marino static struct head libraries; /* list of shared libraries found */ 2771*e4b17023SJohn Marino struct id *list; 2772*e4b17023SJohn Marino void (*int_handler) (int); 2773*e4b17023SJohn Marino #ifdef SIGQUIT 2774*e4b17023SJohn Marino void (*quit_handler) (int); 2775*e4b17023SJohn Marino #endif 2776*e4b17023SJohn Marino char *real_ldd_argv[4]; 2777*e4b17023SJohn Marino const char **ldd_argv = CONST_CAST2 (const char **, char **, real_ldd_argv); 2778*e4b17023SJohn Marino int argc = 0; 2779*e4b17023SJohn Marino struct pex_obj *pex; 2780*e4b17023SJohn Marino const char *errmsg; 2781*e4b17023SJohn Marino int err; 2782*e4b17023SJohn Marino char buf[1024]; 2783*e4b17023SJohn Marino FILE *inf; 2784*e4b17023SJohn Marino 2785*e4b17023SJohn Marino /* If we do not have an `ldd', complain. */ 2786*e4b17023SJohn Marino if (ldd_file_name == 0) 2787*e4b17023SJohn Marino { 2788*e4b17023SJohn Marino error ("cannot find 'ldd'"); 2789*e4b17023SJohn Marino return; 2790*e4b17023SJohn Marino } 2791*e4b17023SJohn Marino 2792*e4b17023SJohn Marino ldd_argv[argc++] = ldd_file_name; 2793*e4b17023SJohn Marino ldd_argv[argc++] = prog_name; 2794*e4b17023SJohn Marino ldd_argv[argc++] = (char *) 0; 2795*e4b17023SJohn Marino 2796*e4b17023SJohn Marino /* Trace if needed. */ 2797*e4b17023SJohn Marino if (vflag) 2798*e4b17023SJohn Marino { 2799*e4b17023SJohn Marino const char **p_argv; 2800*e4b17023SJohn Marino const char *str; 2801*e4b17023SJohn Marino 2802*e4b17023SJohn Marino for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++) 2803*e4b17023SJohn Marino fprintf (stderr, " %s", str); 2804*e4b17023SJohn Marino 2805*e4b17023SJohn Marino fprintf (stderr, "\n"); 2806*e4b17023SJohn Marino } 2807*e4b17023SJohn Marino 2808*e4b17023SJohn Marino fflush (stdout); 2809*e4b17023SJohn Marino fflush (stderr); 2810*e4b17023SJohn Marino 2811*e4b17023SJohn Marino pex = pex_init (PEX_USE_PIPES, "collect2", NULL); 2812*e4b17023SJohn Marino if (pex == NULL) 2813*e4b17023SJohn Marino fatal_error ("pex_init failed: %m"); 2814*e4b17023SJohn Marino 2815*e4b17023SJohn Marino errmsg = pex_run (pex, 0, ldd_file_name, real_ldd_argv, NULL, NULL, &err); 2816*e4b17023SJohn Marino if (errmsg != NULL) 2817*e4b17023SJohn Marino { 2818*e4b17023SJohn Marino if (err != 0) 2819*e4b17023SJohn Marino { 2820*e4b17023SJohn Marino errno = err; 2821*e4b17023SJohn Marino fatal_error ("%s: %m", _(errmsg)); 2822*e4b17023SJohn Marino } 2823*e4b17023SJohn Marino else 2824*e4b17023SJohn Marino fatal_error (errmsg); 2825*e4b17023SJohn Marino } 2826*e4b17023SJohn Marino 2827*e4b17023SJohn Marino int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN); 2828*e4b17023SJohn Marino #ifdef SIGQUIT 2829*e4b17023SJohn Marino quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN); 2830*e4b17023SJohn Marino #endif 2831*e4b17023SJohn Marino 2832*e4b17023SJohn Marino inf = pex_read_output (pex, 0); 2833*e4b17023SJohn Marino if (inf == NULL) 2834*e4b17023SJohn Marino fatal_error ("can't open ldd output: %m"); 2835*e4b17023SJohn Marino 2836*e4b17023SJohn Marino if (debug) 2837*e4b17023SJohn Marino notice ("\nldd output with constructors/destructors.\n"); 2838*e4b17023SJohn Marino 2839*e4b17023SJohn Marino /* Read each line of ldd output. */ 2840*e4b17023SJohn Marino while (fgets (buf, sizeof buf, inf) != (char *) 0) 2841*e4b17023SJohn Marino { 2842*e4b17023SJohn Marino int ch2; 2843*e4b17023SJohn Marino char *name, *end, *p = buf; 2844*e4b17023SJohn Marino 2845*e4b17023SJohn Marino /* Extract names of libraries and add to list. */ 2846*e4b17023SJohn Marino PARSE_LDD_OUTPUT (p); 2847*e4b17023SJohn Marino if (p == 0) 2848*e4b17023SJohn Marino continue; 2849*e4b17023SJohn Marino 2850*e4b17023SJohn Marino name = p; 2851*e4b17023SJohn Marino if (strncmp (name, "not found", sizeof ("not found") - 1) == 0) 2852*e4b17023SJohn Marino fatal_error ("dynamic dependency %s not found", buf); 2853*e4b17023SJohn Marino 2854*e4b17023SJohn Marino /* Find the end of the symbol name. */ 2855*e4b17023SJohn Marino for (end = p; 2856*e4b17023SJohn Marino (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|'; 2857*e4b17023SJohn Marino end++) 2858*e4b17023SJohn Marino continue; 2859*e4b17023SJohn Marino *end = '\0'; 2860*e4b17023SJohn Marino 2861*e4b17023SJohn Marino if (access (name, R_OK) == 0) 2862*e4b17023SJohn Marino add_to_list (&libraries, name); 2863*e4b17023SJohn Marino else 2864*e4b17023SJohn Marino fatal_error ("unable to open dynamic dependency '%s'", buf); 2865*e4b17023SJohn Marino 2866*e4b17023SJohn Marino if (debug) 2867*e4b17023SJohn Marino fprintf (stderr, "\t%s\n", buf); 2868*e4b17023SJohn Marino } 2869*e4b17023SJohn Marino if (debug) 2870*e4b17023SJohn Marino fprintf (stderr, "\n"); 2871*e4b17023SJohn Marino 2872*e4b17023SJohn Marino do_wait (ldd_file_name, pex); 2873*e4b17023SJohn Marino 2874*e4b17023SJohn Marino signal (SIGINT, int_handler); 2875*e4b17023SJohn Marino #ifdef SIGQUIT 2876*e4b17023SJohn Marino signal (SIGQUIT, quit_handler); 2877*e4b17023SJohn Marino #endif 2878*e4b17023SJohn Marino 2879*e4b17023SJohn Marino /* Now iterate through the library list adding their symbols to 2880*e4b17023SJohn Marino the list. */ 2881*e4b17023SJohn Marino for (list = libraries.first; list; list = list->next) 2882*e4b17023SJohn Marino scan_prog_file (list->name, PASS_LIB, SCAN_ALL); 2883*e4b17023SJohn Marino } 2884*e4b17023SJohn Marino 2885*e4b17023SJohn Marino #endif /* LDD_SUFFIX */ 2886*e4b17023SJohn Marino 2887*e4b17023SJohn Marino #endif /* OBJECT_FORMAT_NONE */ 2888*e4b17023SJohn Marino 2889*e4b17023SJohn Marino 2890*e4b17023SJohn Marino /* 2891*e4b17023SJohn Marino * COFF specific stuff. 2892*e4b17023SJohn Marino */ 2893*e4b17023SJohn Marino 2894*e4b17023SJohn Marino #ifdef OBJECT_FORMAT_COFF 2895*e4b17023SJohn Marino 2896*e4b17023SJohn Marino #if defined (EXTENDED_COFF) 2897*e4b17023SJohn Marino 2898*e4b17023SJohn Marino # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax) 2899*e4b17023SJohn Marino # define GCC_SYMENT SYMR 2900*e4b17023SJohn Marino # define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal) 2901*e4b17023SJohn Marino # define GCC_SYMINC(X) (1) 2902*e4b17023SJohn Marino # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax) 2903*e4b17023SJohn Marino # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0) 2904*e4b17023SJohn Marino 2905*e4b17023SJohn Marino #else 2906*e4b17023SJohn Marino 2907*e4b17023SJohn Marino # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms) 2908*e4b17023SJohn Marino # define GCC_SYMENT SYMENT 2909*e4b17023SJohn Marino # if defined (C_WEAKEXT) 2910*e4b17023SJohn Marino # define GCC_OK_SYMBOL(X) \ 2911*e4b17023SJohn Marino (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \ 2912*e4b17023SJohn Marino ((X).n_scnum > N_UNDEF) && \ 2913*e4b17023SJohn Marino (aix64_flag \ 2914*e4b17023SJohn Marino || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \ 2915*e4b17023SJohn Marino || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))) 2916*e4b17023SJohn Marino # define GCC_UNDEF_SYMBOL(X) \ 2917*e4b17023SJohn Marino (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \ 2918*e4b17023SJohn Marino ((X).n_scnum == N_UNDEF)) 2919*e4b17023SJohn Marino # else 2920*e4b17023SJohn Marino # define GCC_OK_SYMBOL(X) \ 2921*e4b17023SJohn Marino (((X).n_sclass == C_EXT) && \ 2922*e4b17023SJohn Marino ((X).n_scnum > N_UNDEF) && \ 2923*e4b17023SJohn Marino (aix64_flag \ 2924*e4b17023SJohn Marino || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \ 2925*e4b17023SJohn Marino || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))) 2926*e4b17023SJohn Marino # define GCC_UNDEF_SYMBOL(X) \ 2927*e4b17023SJohn Marino (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF)) 2928*e4b17023SJohn Marino # endif 2929*e4b17023SJohn Marino # define GCC_SYMINC(X) ((X).n_numaux+1) 2930*e4b17023SJohn Marino # define GCC_SYMZERO(X) 0 2931*e4b17023SJohn Marino 2932*e4b17023SJohn Marino /* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */ 2933*e4b17023SJohn Marino #if TARGET_AIX_VERSION >= 51 2934*e4b17023SJohn Marino # define GCC_CHECK_HDR(X) \ 2935*e4b17023SJohn Marino ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \ 2936*e4b17023SJohn Marino || (HEADER (X).f_magic == 0767 && aix64_flag)) 2937*e4b17023SJohn Marino #else 2938*e4b17023SJohn Marino # define GCC_CHECK_HDR(X) \ 2939*e4b17023SJohn Marino ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \ 2940*e4b17023SJohn Marino || (HEADER (X).f_magic == 0757 && aix64_flag)) 2941*e4b17023SJohn Marino #endif 2942*e4b17023SJohn Marino 2943*e4b17023SJohn Marino #endif 2944*e4b17023SJohn Marino 2945*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 2946*e4b17023SJohn Marino /* Array of standard AIX libraries which should not 2947*e4b17023SJohn Marino be scanned for ctors/dtors. */ 2948*e4b17023SJohn Marino static const char *const aix_std_libs[] = { 2949*e4b17023SJohn Marino "/unix", 2950*e4b17023SJohn Marino "/lib/libc.a", 2951*e4b17023SJohn Marino "/lib/libm.a", 2952*e4b17023SJohn Marino "/lib/libc_r.a", 2953*e4b17023SJohn Marino "/lib/libm_r.a", 2954*e4b17023SJohn Marino "/usr/lib/libc.a", 2955*e4b17023SJohn Marino "/usr/lib/libm.a", 2956*e4b17023SJohn Marino "/usr/lib/libc_r.a", 2957*e4b17023SJohn Marino "/usr/lib/libm_r.a", 2958*e4b17023SJohn Marino "/usr/lib/threads/libc.a", 2959*e4b17023SJohn Marino "/usr/ccs/lib/libc.a", 2960*e4b17023SJohn Marino "/usr/ccs/lib/libm.a", 2961*e4b17023SJohn Marino "/usr/ccs/lib/libc_r.a", 2962*e4b17023SJohn Marino "/usr/ccs/lib/libm_r.a", 2963*e4b17023SJohn Marino NULL 2964*e4b17023SJohn Marino }; 2965*e4b17023SJohn Marino 2966*e4b17023SJohn Marino /* This function checks the filename and returns 1 2967*e4b17023SJohn Marino if this name matches the location of a standard AIX library. */ 2968*e4b17023SJohn Marino static int ignore_library (const char *); 2969*e4b17023SJohn Marino static int 2970*e4b17023SJohn Marino ignore_library (const char *name) 2971*e4b17023SJohn Marino { 2972*e4b17023SJohn Marino const char *const *p; 2973*e4b17023SJohn Marino size_t length; 2974*e4b17023SJohn Marino 2975*e4b17023SJohn Marino if (target_system_root[0] != '\0') 2976*e4b17023SJohn Marino { 2977*e4b17023SJohn Marino length = strlen (target_system_root); 2978*e4b17023SJohn Marino if (strncmp (name, target_system_root, length) != 0) 2979*e4b17023SJohn Marino return 0; 2980*e4b17023SJohn Marino name += length; 2981*e4b17023SJohn Marino } 2982*e4b17023SJohn Marino for (p = &aix_std_libs[0]; *p != NULL; ++p) 2983*e4b17023SJohn Marino if (strcmp (name, *p) == 0) 2984*e4b17023SJohn Marino return 1; 2985*e4b17023SJohn Marino return 0; 2986*e4b17023SJohn Marino } 2987*e4b17023SJohn Marino #endif /* COLLECT_EXPORT_LIST */ 2988*e4b17023SJohn Marino 2989*e4b17023SJohn Marino #if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME 2990*e4b17023SJohn Marino extern char *ldgetname (LDFILE *, GCC_SYMENT *); 2991*e4b17023SJohn Marino #endif 2992*e4b17023SJohn Marino 2993*e4b17023SJohn Marino /* COFF version to scan the name list of the loaded program for 2994*e4b17023SJohn Marino the symbols g++ uses for static constructors and destructors. */ 2995*e4b17023SJohn Marino 2996*e4b17023SJohn Marino static void 2997*e4b17023SJohn Marino scan_prog_file (const char *prog_name, scanpass which_pass, 2998*e4b17023SJohn Marino scanfilter filter) 2999*e4b17023SJohn Marino { 3000*e4b17023SJohn Marino LDFILE *ldptr = NULL; 3001*e4b17023SJohn Marino int sym_index, sym_count; 3002*e4b17023SJohn Marino int is_shared = 0; 3003*e4b17023SJohn Marino 3004*e4b17023SJohn Marino if (which_pass != PASS_FIRST && which_pass != PASS_OBJ) 3005*e4b17023SJohn Marino return; 3006*e4b17023SJohn Marino 3007*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 3008*e4b17023SJohn Marino /* We do not need scanning for some standard C libraries. */ 3009*e4b17023SJohn Marino if (which_pass == PASS_FIRST && ignore_library (prog_name)) 3010*e4b17023SJohn Marino return; 3011*e4b17023SJohn Marino 3012*e4b17023SJohn Marino /* On AIX we have a loop, because there is not much difference 3013*e4b17023SJohn Marino between an object and an archive. This trick allows us to 3014*e4b17023SJohn Marino eliminate scan_libraries() function. */ 3015*e4b17023SJohn Marino do 3016*e4b17023SJohn Marino { 3017*e4b17023SJohn Marino #endif 3018*e4b17023SJohn Marino /* Some platforms (e.g. OSF4) declare ldopen as taking a 3019*e4b17023SJohn Marino non-const char * filename parameter, even though it will not 3020*e4b17023SJohn Marino modify that string. So we must cast away const-ness here, 3021*e4b17023SJohn Marino using CONST_CAST to prevent complaints from -Wcast-qual. */ 3022*e4b17023SJohn Marino if ((ldptr = ldopen (CONST_CAST (char *, prog_name), ldptr)) != NULL) 3023*e4b17023SJohn Marino { 3024*e4b17023SJohn Marino if (! MY_ISCOFF (HEADER (ldptr).f_magic)) 3025*e4b17023SJohn Marino fatal_error ("%s: not a COFF file", prog_name); 3026*e4b17023SJohn Marino 3027*e4b17023SJohn Marino if (GCC_CHECK_HDR (ldptr)) 3028*e4b17023SJohn Marino { 3029*e4b17023SJohn Marino sym_count = GCC_SYMBOLS (ldptr); 3030*e4b17023SJohn Marino sym_index = GCC_SYMZERO (ldptr); 3031*e4b17023SJohn Marino 3032*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 3033*e4b17023SJohn Marino /* Is current archive member a shared object? */ 3034*e4b17023SJohn Marino is_shared = HEADER (ldptr).f_flags & F_SHROBJ; 3035*e4b17023SJohn Marino #endif 3036*e4b17023SJohn Marino 3037*e4b17023SJohn Marino while (sym_index < sym_count) 3038*e4b17023SJohn Marino { 3039*e4b17023SJohn Marino GCC_SYMENT symbol; 3040*e4b17023SJohn Marino 3041*e4b17023SJohn Marino if (ldtbread (ldptr, sym_index, &symbol) <= 0) 3042*e4b17023SJohn Marino break; 3043*e4b17023SJohn Marino sym_index += GCC_SYMINC (symbol); 3044*e4b17023SJohn Marino 3045*e4b17023SJohn Marino if (GCC_OK_SYMBOL (symbol)) 3046*e4b17023SJohn Marino { 3047*e4b17023SJohn Marino char *name; 3048*e4b17023SJohn Marino 3049*e4b17023SJohn Marino if ((name = ldgetname (ldptr, &symbol)) == NULL) 3050*e4b17023SJohn Marino continue; /* Should never happen. */ 3051*e4b17023SJohn Marino 3052*e4b17023SJohn Marino #ifdef XCOFF_DEBUGGING_INFO 3053*e4b17023SJohn Marino /* All AIX function names have a duplicate entry 3054*e4b17023SJohn Marino beginning with a dot. */ 3055*e4b17023SJohn Marino if (*name == '.') 3056*e4b17023SJohn Marino ++name; 3057*e4b17023SJohn Marino #endif 3058*e4b17023SJohn Marino 3059*e4b17023SJohn Marino switch (is_ctor_dtor (name)) 3060*e4b17023SJohn Marino { 3061*e4b17023SJohn Marino case SYM_CTOR: 3062*e4b17023SJohn Marino if (! (filter & SCAN_CTOR)) 3063*e4b17023SJohn Marino break; 3064*e4b17023SJohn Marino if (! is_shared) 3065*e4b17023SJohn Marino add_to_list (&constructors, name); 3066*e4b17023SJohn Marino #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH) 3067*e4b17023SJohn Marino if (which_pass == PASS_OBJ) 3068*e4b17023SJohn Marino add_to_list (&exports, name); 3069*e4b17023SJohn Marino #endif 3070*e4b17023SJohn Marino break; 3071*e4b17023SJohn Marino 3072*e4b17023SJohn Marino case SYM_DTOR: 3073*e4b17023SJohn Marino if (! (filter & SCAN_DTOR)) 3074*e4b17023SJohn Marino break; 3075*e4b17023SJohn Marino if (! is_shared) 3076*e4b17023SJohn Marino add_to_list (&destructors, name); 3077*e4b17023SJohn Marino #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH) 3078*e4b17023SJohn Marino if (which_pass == PASS_OBJ) 3079*e4b17023SJohn Marino add_to_list (&exports, name); 3080*e4b17023SJohn Marino #endif 3081*e4b17023SJohn Marino break; 3082*e4b17023SJohn Marino 3083*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 3084*e4b17023SJohn Marino case SYM_INIT: 3085*e4b17023SJohn Marino if (! (filter & SCAN_INIT)) 3086*e4b17023SJohn Marino break; 3087*e4b17023SJohn Marino #ifndef LD_INIT_SWITCH 3088*e4b17023SJohn Marino if (is_shared) 3089*e4b17023SJohn Marino add_to_list (&constructors, name); 3090*e4b17023SJohn Marino #endif 3091*e4b17023SJohn Marino break; 3092*e4b17023SJohn Marino 3093*e4b17023SJohn Marino case SYM_FINI: 3094*e4b17023SJohn Marino if (! (filter & SCAN_FINI)) 3095*e4b17023SJohn Marino break; 3096*e4b17023SJohn Marino #ifndef LD_INIT_SWITCH 3097*e4b17023SJohn Marino if (is_shared) 3098*e4b17023SJohn Marino add_to_list (&destructors, name); 3099*e4b17023SJohn Marino #endif 3100*e4b17023SJohn Marino break; 3101*e4b17023SJohn Marino #endif 3102*e4b17023SJohn Marino 3103*e4b17023SJohn Marino case SYM_DWEH: 3104*e4b17023SJohn Marino if (! (filter & SCAN_DWEH)) 3105*e4b17023SJohn Marino break; 3106*e4b17023SJohn Marino if (! is_shared) 3107*e4b17023SJohn Marino add_to_list (&frame_tables, name); 3108*e4b17023SJohn Marino #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH) 3109*e4b17023SJohn Marino if (which_pass == PASS_OBJ) 3110*e4b17023SJohn Marino add_to_list (&exports, name); 3111*e4b17023SJohn Marino #endif 3112*e4b17023SJohn Marino break; 3113*e4b17023SJohn Marino 3114*e4b17023SJohn Marino default: /* not a constructor or destructor */ 3115*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 3116*e4b17023SJohn Marino /* Explicitly export all global symbols when 3117*e4b17023SJohn Marino building a shared object on AIX, but do not 3118*e4b17023SJohn Marino re-export symbols from another shared object 3119*e4b17023SJohn Marino and do not export symbols if the user 3120*e4b17023SJohn Marino provides an explicit export list. */ 3121*e4b17023SJohn Marino if (shared_obj && !is_shared 3122*e4b17023SJohn Marino && which_pass == PASS_OBJ && !export_flag) 3123*e4b17023SJohn Marino add_to_list (&exports, name); 3124*e4b17023SJohn Marino #endif 3125*e4b17023SJohn Marino continue; 3126*e4b17023SJohn Marino } 3127*e4b17023SJohn Marino 3128*e4b17023SJohn Marino if (debug) 3129*e4b17023SJohn Marino #if !defined(EXTENDED_COFF) 3130*e4b17023SJohn Marino fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n", 3131*e4b17023SJohn Marino symbol.n_scnum, symbol.n_sclass, 3132*e4b17023SJohn Marino (symbol.n_type ? "0" : ""), symbol.n_type, 3133*e4b17023SJohn Marino name); 3134*e4b17023SJohn Marino #else 3135*e4b17023SJohn Marino fprintf (stderr, 3136*e4b17023SJohn Marino "\tiss = %5d, value = %5ld, index = %5d, name = %s\n", 3137*e4b17023SJohn Marino symbol.iss, (long) symbol.value, symbol.index, name); 3138*e4b17023SJohn Marino #endif 3139*e4b17023SJohn Marino } 3140*e4b17023SJohn Marino } 3141*e4b17023SJohn Marino } 3142*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 3143*e4b17023SJohn Marino else 3144*e4b17023SJohn Marino { 3145*e4b17023SJohn Marino /* If archive contains both 32-bit and 64-bit objects, 3146*e4b17023SJohn Marino we want to skip objects in other mode so mismatch normal. */ 3147*e4b17023SJohn Marino if (debug) 3148*e4b17023SJohn Marino fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n", 3149*e4b17023SJohn Marino prog_name, HEADER (ldptr).f_magic, aix64_flag); 3150*e4b17023SJohn Marino } 3151*e4b17023SJohn Marino #endif 3152*e4b17023SJohn Marino } 3153*e4b17023SJohn Marino else 3154*e4b17023SJohn Marino { 3155*e4b17023SJohn Marino fatal_error ("%s: cannot open as COFF file", prog_name); 3156*e4b17023SJohn Marino } 3157*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 3158*e4b17023SJohn Marino /* On AIX loop continues while there are more members in archive. */ 3159*e4b17023SJohn Marino } 3160*e4b17023SJohn Marino while (ldclose (ldptr) == FAILURE); 3161*e4b17023SJohn Marino #else 3162*e4b17023SJohn Marino /* Otherwise we simply close ldptr. */ 3163*e4b17023SJohn Marino (void) ldclose(ldptr); 3164*e4b17023SJohn Marino #endif 3165*e4b17023SJohn Marino } 3166*e4b17023SJohn Marino #endif /* OBJECT_FORMAT_COFF */ 3167*e4b17023SJohn Marino 3168*e4b17023SJohn Marino #ifdef COLLECT_EXPORT_LIST 3169*e4b17023SJohn Marino /* Given a library name without "lib" prefix, this function 3170*e4b17023SJohn Marino returns a full library name including a path. */ 3171*e4b17023SJohn Marino static char * 3172*e4b17023SJohn Marino resolve_lib_name (const char *name) 3173*e4b17023SJohn Marino { 3174*e4b17023SJohn Marino char *lib_buf; 3175*e4b17023SJohn Marino int i, j, l = 0; 3176*e4b17023SJohn Marino /* Library extensions for AIX dynamic linking. */ 3177*e4b17023SJohn Marino const char * const libexts[2] = {"a", "so"}; 3178*e4b17023SJohn Marino 3179*e4b17023SJohn Marino for (i = 0; libpaths[i]; i++) 3180*e4b17023SJohn Marino if (libpaths[i]->max_len > l) 3181*e4b17023SJohn Marino l = libpaths[i]->max_len; 3182*e4b17023SJohn Marino 3183*e4b17023SJohn Marino lib_buf = XNEWVEC (char, l + strlen(name) + 10); 3184*e4b17023SJohn Marino 3185*e4b17023SJohn Marino for (i = 0; libpaths[i]; i++) 3186*e4b17023SJohn Marino { 3187*e4b17023SJohn Marino struct prefix_list *list = libpaths[i]->plist; 3188*e4b17023SJohn Marino for (; list; list = list->next) 3189*e4b17023SJohn Marino { 3190*e4b17023SJohn Marino /* The following lines are needed because path_prefix list 3191*e4b17023SJohn Marino may contain directories both with trailing DIR_SEPARATOR and 3192*e4b17023SJohn Marino without it. */ 3193*e4b17023SJohn Marino const char *p = ""; 3194*e4b17023SJohn Marino if (!IS_DIR_SEPARATOR (list->prefix[strlen(list->prefix)-1])) 3195*e4b17023SJohn Marino p = "/"; 3196*e4b17023SJohn Marino for (j = 0; j < 2; j++) 3197*e4b17023SJohn Marino { 3198*e4b17023SJohn Marino sprintf (lib_buf, "%s%slib%s.%s", 3199*e4b17023SJohn Marino list->prefix, p, name, 3200*e4b17023SJohn Marino libexts[(j + aixrtl_flag) % 2]); 3201*e4b17023SJohn Marino if (debug) fprintf (stderr, "searching for: %s\n", lib_buf); 3202*e4b17023SJohn Marino if (file_exists (lib_buf)) 3203*e4b17023SJohn Marino { 3204*e4b17023SJohn Marino if (debug) fprintf (stderr, "found: %s\n", lib_buf); 3205*e4b17023SJohn Marino return (lib_buf); 3206*e4b17023SJohn Marino } 3207*e4b17023SJohn Marino } 3208*e4b17023SJohn Marino } 3209*e4b17023SJohn Marino } 3210*e4b17023SJohn Marino if (debug) 3211*e4b17023SJohn Marino fprintf (stderr, "not found\n"); 3212*e4b17023SJohn Marino else 3213*e4b17023SJohn Marino fatal_error ("library lib%s not found", name); 3214*e4b17023SJohn Marino return (NULL); 3215*e4b17023SJohn Marino } 3216*e4b17023SJohn Marino #endif /* COLLECT_EXPORT_LIST */ 3217*e4b17023SJohn Marino 3218*e4b17023SJohn Marino #ifdef COLLECT_RUN_DSYMUTIL 3219*e4b17023SJohn Marino static int flag_dsym = false; 3220*e4b17023SJohn Marino static int flag_idsym = false; 3221*e4b17023SJohn Marino 3222*e4b17023SJohn Marino static void 3223*e4b17023SJohn Marino process_args (int *argcp, char **argv) { 3224*e4b17023SJohn Marino int i, j; 3225*e4b17023SJohn Marino int argc = *argcp; 3226*e4b17023SJohn Marino for (i=0; i<argc; ++i) 3227*e4b17023SJohn Marino { 3228*e4b17023SJohn Marino if (strcmp (argv[i], "-dsym") == 0) 3229*e4b17023SJohn Marino { 3230*e4b17023SJohn Marino flag_dsym = true; 3231*e4b17023SJohn Marino /* Remove the flag, as we handle all processing for it. */ 3232*e4b17023SJohn Marino j = i; 3233*e4b17023SJohn Marino do 3234*e4b17023SJohn Marino argv[j] = argv[j+1]; 3235*e4b17023SJohn Marino while (++j < argc); 3236*e4b17023SJohn Marino --i; 3237*e4b17023SJohn Marino argc = --(*argcp); 3238*e4b17023SJohn Marino } 3239*e4b17023SJohn Marino else if (strcmp (argv[i], "-idsym") == 0) 3240*e4b17023SJohn Marino { 3241*e4b17023SJohn Marino flag_idsym = true; 3242*e4b17023SJohn Marino /* Remove the flag, as we handle all processing for it. */ 3243*e4b17023SJohn Marino j = i; 3244*e4b17023SJohn Marino do 3245*e4b17023SJohn Marino argv[j] = argv[j+1]; 3246*e4b17023SJohn Marino while (++j < argc); 3247*e4b17023SJohn Marino --i; 3248*e4b17023SJohn Marino argc = --(*argcp); 3249*e4b17023SJohn Marino } 3250*e4b17023SJohn Marino } 3251*e4b17023SJohn Marino } 3252*e4b17023SJohn Marino 3253*e4b17023SJohn Marino static void 3254*e4b17023SJohn Marino do_dsymutil (const char *output_file) { 3255*e4b17023SJohn Marino const char *dsymutil = DSYMUTIL + 1; 3256*e4b17023SJohn Marino struct pex_obj *pex; 3257*e4b17023SJohn Marino char **real_argv = XCNEWVEC (char *, 3); 3258*e4b17023SJohn Marino const char ** argv = CONST_CAST2 (const char **, char **, 3259*e4b17023SJohn Marino real_argv); 3260*e4b17023SJohn Marino 3261*e4b17023SJohn Marino argv[0] = dsymutil; 3262*e4b17023SJohn Marino argv[1] = output_file; 3263*e4b17023SJohn Marino argv[2] = (char *) 0; 3264*e4b17023SJohn Marino 3265*e4b17023SJohn Marino pex = collect_execute (dsymutil, real_argv, NULL, NULL, PEX_LAST | PEX_SEARCH); 3266*e4b17023SJohn Marino do_wait (dsymutil, pex); 3267*e4b17023SJohn Marino } 3268*e4b17023SJohn Marino 3269*e4b17023SJohn Marino static void 3270*e4b17023SJohn Marino post_ld_pass (bool temp_file) { 3271*e4b17023SJohn Marino if (!(temp_file && flag_idsym) && !flag_dsym) 3272*e4b17023SJohn Marino return; 3273*e4b17023SJohn Marino 3274*e4b17023SJohn Marino do_dsymutil (output_file); 3275*e4b17023SJohn Marino } 3276*e4b17023SJohn Marino #else 3277*e4b17023SJohn Marino static void 3278*e4b17023SJohn Marino process_args (int *argcp ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { } 3279*e4b17023SJohn Marino static void post_ld_pass (bool temp_file ATTRIBUTE_UNUSED) { } 3280*e4b17023SJohn Marino #endif 3281