133965Sjdp/* Parse options for the GNU linker.
278828Sobrien   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3218822Sdim   2001, 2002, 2003, 2004, 2005, 2006, 2007
438889Sjdp   Free Software Foundation, Inc.
533965Sjdp
6130561Sobrien   This file is part of GLD, the Gnu Linker.
733965Sjdp
8130561Sobrien   GLD is free software; you can redistribute it and/or modify
9130561Sobrien   it under the terms of the GNU General Public License as published by
10130561Sobrien   the Free Software Foundation; either version 2, or (at your option)
11130561Sobrien   any later version.
1233965Sjdp
13130561Sobrien   GLD is distributed in the hope that it will be useful,
14130561Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
15130561Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16130561Sobrien   GNU General Public License for more details.
1733965Sjdp
18130561Sobrien   You should have received a copy of the GNU General Public License
19130561Sobrien   along with GLD; see the file COPYING.  If not, write to the Free
20218822Sdim   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21218822Sdim   02110-1301, USA.  */
2233965Sjdp
23218822Sdim#include "sysdep.h"
2433965Sjdp#include "bfd.h"
25218822Sdim#include "bfdver.h"
2633965Sjdp#include "libiberty.h"
2733965Sjdp#include <stdio.h>
2833965Sjdp#include <string.h>
2989857Sobrien#include "safe-ctype.h"
3033965Sjdp#include "getopt.h"
3133965Sjdp#include "bfdlink.h"
3233965Sjdp#include "ld.h"
3333965Sjdp#include "ldmain.h"
3433965Sjdp#include "ldmisc.h"
3533965Sjdp#include "ldexp.h"
3633965Sjdp#include "ldlang.h"
37107492Sobrien#include <ldgram.h>
3833965Sjdp#include "ldlex.h"
3933965Sjdp#include "ldfile.h"
4033965Sjdp#include "ldver.h"
4133965Sjdp#include "ldemul.h"
4277298Sobrien#include "demangle.h"
4333965Sjdp
4438889Sjdp#ifndef PATH_SEPARATOR
4538889Sjdp#if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN32__))
4638889Sjdp#define PATH_SEPARATOR ';'
4738889Sjdp#else
4838889Sjdp#define PATH_SEPARATOR ':'
4938889Sjdp#endif
5038889Sjdp#endif
5138889Sjdp
5277298Sobrien/* Somewhere above, sys/stat.h got included . . . .  */
5333965Sjdp#if !defined(S_ISDIR) && defined(S_IFDIR)
5433965Sjdp#define	S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
5533965Sjdp#endif
5633965Sjdp
57130561Sobrienstatic void set_default_dirlist (char *);
58130561Sobrienstatic void set_section_start (char *, char *);
59218822Sdimstatic void set_segment_start (const char *, char *);
60130561Sobrienstatic void help (void);
6133965Sjdp
6233965Sjdp/* Non-zero if we are processing a --defsym from the command line.  */
6333965Sjdpint parsing_defsym = 0;
6433965Sjdp
6533965Sjdp/* Codes used for the long options with no short synonyms.  150 isn't
6633965Sjdp   special; it's just an arbitrary non-ASCII char value.  */
67130561Sobrienenum option_values
68130561Sobrien{
69130561Sobrien  OPTION_ASSERT = 150,
70130561Sobrien  OPTION_CALL_SHARED,
71130561Sobrien  OPTION_CREF,
72130561Sobrien  OPTION_DEFSYM,
73130561Sobrien  OPTION_DEMANGLE,
74130561Sobrien  OPTION_DYNAMIC_LINKER,
75218822Sdim  OPTION_SYSROOT,
76130561Sobrien  OPTION_EB,
77130561Sobrien  OPTION_EL,
78130561Sobrien  OPTION_EMBEDDED_RELOCS,
79130561Sobrien  OPTION_EXPORT_DYNAMIC,
80130561Sobrien  OPTION_HELP,
81130561Sobrien  OPTION_IGNORE,
82130561Sobrien  OPTION_MAP,
83130561Sobrien  OPTION_NO_DEMANGLE,
84130561Sobrien  OPTION_NO_KEEP_MEMORY,
85130561Sobrien  OPTION_NO_WARN_MISMATCH,
86218822Sdim  OPTION_NO_WARN_SEARCH_MISMATCH,
87306136Semaste  OPTION_NO_WARN_FATAL,
88130561Sobrien  OPTION_NOINHIBIT_EXEC,
89130561Sobrien  OPTION_NON_SHARED,
90130561Sobrien  OPTION_NO_WHOLE_ARCHIVE,
91130561Sobrien  OPTION_OFORMAT,
92130561Sobrien  OPTION_RELAX,
93130561Sobrien  OPTION_RETAIN_SYMBOLS_FILE,
94130561Sobrien  OPTION_RPATH,
95130561Sobrien  OPTION_RPATH_LINK,
96130561Sobrien  OPTION_SHARED,
97130561Sobrien  OPTION_SONAME,
98130561Sobrien  OPTION_SORT_COMMON,
99218822Sdim  OPTION_SORT_SECTION,
100130561Sobrien  OPTION_STATS,
101130561Sobrien  OPTION_SYMBOLIC,
102218822Sdim  OPTION_SYMBOLIC_FUNCTIONS,
103130561Sobrien  OPTION_TASK_LINK,
104130561Sobrien  OPTION_TBSS,
105130561Sobrien  OPTION_TDATA,
106130561Sobrien  OPTION_TTEXT,
107130561Sobrien  OPTION_TRADITIONAL_FORMAT,
108130561Sobrien  OPTION_UR,
109130561Sobrien  OPTION_VERBOSE,
110130561Sobrien  OPTION_VERSION,
111130561Sobrien  OPTION_VERSION_SCRIPT,
112130561Sobrien  OPTION_VERSION_EXPORTS_SECTION,
113218822Sdim  OPTION_DYNAMIC_LIST,
114218822Sdim  OPTION_DYNAMIC_LIST_CPP_NEW,
115218822Sdim  OPTION_DYNAMIC_LIST_CPP_TYPEINFO,
116218822Sdim  OPTION_DYNAMIC_LIST_DATA,
117130561Sobrien  OPTION_WARN_COMMON,
118130561Sobrien  OPTION_WARN_CONSTRUCTORS,
119130561Sobrien  OPTION_WARN_FATAL,
120130561Sobrien  OPTION_WARN_MULTIPLE_GP,
121130561Sobrien  OPTION_WARN_ONCE,
122130561Sobrien  OPTION_WARN_SECTION_ALIGN,
123130561Sobrien  OPTION_SPLIT_BY_RELOC,
124130561Sobrien  OPTION_SPLIT_BY_FILE ,
125130561Sobrien  OPTION_WHOLE_ARCHIVE,
126218822Sdim  OPTION_ADD_NEEDED,
127218822Sdim  OPTION_NO_ADD_NEEDED,
128130561Sobrien  OPTION_AS_NEEDED,
129130561Sobrien  OPTION_NO_AS_NEEDED,
130130561Sobrien  OPTION_WRAP,
131130561Sobrien  OPTION_FORCE_EXE_SUFFIX,
132130561Sobrien  OPTION_GC_SECTIONS,
133130561Sobrien  OPTION_NO_GC_SECTIONS,
134218822Sdim  OPTION_PRINT_GC_SECTIONS,
135218822Sdim  OPTION_NO_PRINT_GC_SECTIONS,
136218822Sdim  OPTION_HASH_SIZE,
137130561Sobrien  OPTION_CHECK_SECTIONS,
138130561Sobrien  OPTION_NO_CHECK_SECTIONS,
139130561Sobrien  OPTION_NO_UNDEFINED,
140130561Sobrien  OPTION_INIT,
141130561Sobrien  OPTION_FINI,
142130561Sobrien  OPTION_SECTION_START,
143130561Sobrien  OPTION_UNIQUE,
144130561Sobrien  OPTION_TARGET_HELP,
145130561Sobrien  OPTION_ALLOW_SHLIB_UNDEFINED,
146130561Sobrien  OPTION_NO_ALLOW_SHLIB_UNDEFINED,
147130561Sobrien  OPTION_ALLOW_MULTIPLE_DEFINITION,
148130561Sobrien  OPTION_NO_UNDEFINED_VERSION,
149218822Sdim  OPTION_DEFAULT_SYMVER,
150218822Sdim  OPTION_DEFAULT_IMPORTED_SYMVER,
151130561Sobrien  OPTION_DISCARD_NONE,
152130561Sobrien  OPTION_SPARE_DYNAMIC_TAGS,
153130561Sobrien  OPTION_NO_DEFINE_COMMON,
154130561Sobrien  OPTION_NOSTDLIB,
155130561Sobrien  OPTION_NO_OMAGIC,
156130561Sobrien  OPTION_STRIP_DISCARDED,
157130561Sobrien  OPTION_NO_STRIP_DISCARDED,
158130561Sobrien  OPTION_ACCEPT_UNKNOWN_INPUT_ARCH,
159130561Sobrien  OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH,
160130561Sobrien  OPTION_PIE,
161130561Sobrien  OPTION_UNRESOLVED_SYMBOLS,
162130561Sobrien  OPTION_WARN_UNRESOLVED_SYMBOLS,
163218822Sdim  OPTION_ERROR_UNRESOLVED_SYMBOLS,
164218822Sdim  OPTION_WARN_SHARED_TEXTREL,
165218822Sdim  OPTION_REDUCE_MEMORY_OVERHEADS,
166218822Sdim  OPTION_DEFAULT_SCRIPT
167130561Sobrien};
16833965Sjdp
16933965Sjdp/* The long options.  This structure is used for both the option
17033965Sjdp   parsing and the help text.  */
17133965Sjdp
17233965Sjdpstruct ld_option
17333965Sjdp{
17433965Sjdp  /* The long option information.  */
17533965Sjdp  struct option opt;
17633965Sjdp  /* The short option with the same meaning ('\0' if none).  */
17733965Sjdp  char shortopt;
17833965Sjdp  /* The name of the argument (NULL if none).  */
17933965Sjdp  const char *arg;
18033965Sjdp  /* The documentation string.  If this is NULL, this is a synonym for
18133965Sjdp     the previous option.  */
18233965Sjdp  const char *doc;
18377298Sobrien  enum {
18477298Sobrien    /* Use one dash before long option name.  */
18577298Sobrien    ONE_DASH,
18677298Sobrien    /* Use two dashes before long option name.  */
18777298Sobrien    TWO_DASHES,
18877298Sobrien    /* Only accept two dashes before the long option name.
18977298Sobrien       This is an overloading of the use of this enum, since originally it
19077298Sobrien       was only intended to tell the --help display function how to display
19177298Sobrien       the long option name.  This feature was added in order to resolve
19277298Sobrien       the confusion about the -omagic command line switch.  Is it setting
19377298Sobrien       the output file name to "magic" or is it setting the NMAGIC flag on
19477298Sobrien       the output ?  It has been decided that it is setting the output file
19577298Sobrien       name, and that if you want to set the NMAGIC flag you should use -N
19677298Sobrien       or --omagic.  */
19777298Sobrien    EXACTLY_TWO_DASHES,
19877298Sobrien    /* Don't mention this option in --help output.  */
19977298Sobrien    NO_HELP
20077298Sobrien  } control;
20133965Sjdp};
20233965Sjdp
20333965Sjdpstatic const struct ld_option ld_options[] =
20433965Sjdp{
20533965Sjdp  { {NULL, required_argument, NULL, '\0'},
206218822Sdim    'a', N_("KEYWORD"), N_("Shared library control for HP/UX compatibility"),
207218822Sdim    ONE_DASH },
20833965Sjdp  { {"architecture", required_argument, NULL, 'A'},
209218822Sdim    'A', N_("ARCH"), N_("Set architecture") , TWO_DASHES },
21033965Sjdp  { {"format", required_argument, NULL, 'b'},
211218822Sdim    'b', N_("TARGET"), N_("Specify target for following input files"),
212218822Sdim    TWO_DASHES },
21333965Sjdp  { {"mri-script", required_argument, NULL, 'c'},
214218822Sdim    'c', N_("FILE"), N_("Read MRI format linker script"), TWO_DASHES },
21533965Sjdp  { {"dc", no_argument, NULL, 'd'},
216218822Sdim    'd', NULL, N_("Force common symbols to be defined"), ONE_DASH },
21733965Sjdp  { {"dp", no_argument, NULL, 'd'},
218218822Sdim    '\0', NULL, NULL, ONE_DASH },
21933965Sjdp  { {"entry", required_argument, NULL, 'e'},
220218822Sdim    'e', N_("ADDRESS"), N_("Set start address"), TWO_DASHES },
22133965Sjdp  { {"export-dynamic", no_argument, NULL, OPTION_EXPORT_DYNAMIC},
222218822Sdim    'E', NULL, N_("Export all dynamic symbols"), TWO_DASHES },
22360484Sobrien  { {"EB", no_argument, NULL, OPTION_EB},
224218822Sdim    '\0', NULL, N_("Link big-endian objects"), ONE_DASH },
22560484Sobrien  { {"EL", no_argument, NULL, OPTION_EL},
226218822Sdim    '\0', NULL, N_("Link little-endian objects"), ONE_DASH },
22733965Sjdp  { {"auxiliary", required_argument, NULL, 'f'},
228218822Sdim    'f', N_("SHLIB"), N_("Auxiliary filter for shared object symbol table"),
229218822Sdim    TWO_DASHES },
23033965Sjdp  { {"filter", required_argument, NULL, 'F'},
231218822Sdim    'F', N_("SHLIB"), N_("Filter for shared object symbol table"),
232218822Sdim    TWO_DASHES },
23333965Sjdp  { {NULL, no_argument, NULL, '\0'},
234218822Sdim    'g', NULL, N_("Ignored"), ONE_DASH },
23533965Sjdp  { {"gpsize", required_argument, NULL, 'G'},
236218822Sdim    'G', N_("SIZE"), N_("Small data size (if no size, same as --shared)"),
237218822Sdim    TWO_DASHES },
23833965Sjdp  { {"soname", required_argument, NULL, OPTION_SONAME},
239218822Sdim    'h', N_("FILENAME"), N_("Set internal name of shared library"), ONE_DASH },
24089857Sobrien  { {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER},
241218822Sdim    'I', N_("PROGRAM"), N_("Set PROGRAM as the dynamic linker to use"),
242218822Sdim    TWO_DASHES },
24333965Sjdp  { {"library", required_argument, NULL, 'l'},
244218822Sdim    'l', N_("LIBNAME"), N_("Search for library LIBNAME"), TWO_DASHES },
24533965Sjdp  { {"library-path", required_argument, NULL, 'L'},
246218822Sdim    'L', N_("DIRECTORY"), N_("Add DIRECTORY to library search path"),
247218822Sdim    TWO_DASHES },
248218822Sdim  { {"sysroot=<DIRECTORY>", required_argument, NULL, OPTION_SYSROOT},
249218822Sdim    '\0', NULL, N_("Override the default sysroot location"), TWO_DASHES },
25033965Sjdp  { {NULL, required_argument, NULL, '\0'},
251218822Sdim    'm', N_("EMULATION"), N_("Set emulation"), ONE_DASH },
25233965Sjdp  { {"print-map", no_argument, NULL, 'M'},
253218822Sdim    'M', NULL, N_("Print map file on standard output"), TWO_DASHES },
25433965Sjdp  { {"nmagic", no_argument, NULL, 'n'},
255218822Sdim    'n', NULL, N_("Do not page align data"), TWO_DASHES },
25633965Sjdp  { {"omagic", no_argument, NULL, 'N'},
257218822Sdim    'N', NULL, N_("Do not page align data, do not make text readonly"),
258218822Sdim    EXACTLY_TWO_DASHES },
259130561Sobrien  { {"no-omagic", no_argument, NULL, OPTION_NO_OMAGIC},
260218822Sdim    '\0', NULL, N_("Page align data, make text readonly"),
261218822Sdim    EXACTLY_TWO_DASHES },
26233965Sjdp  { {"output", required_argument, NULL, 'o'},
263218822Sdim    'o', N_("FILE"), N_("Set output file name"), EXACTLY_TWO_DASHES },
26433965Sjdp  { {NULL, required_argument, NULL, '\0'},
265218822Sdim    'O', NULL, N_("Optimize output file"), ONE_DASH },
26660484Sobrien  { {"Qy", no_argument, NULL, OPTION_IGNORE},
267218822Sdim    '\0', NULL, N_("Ignored for SVR4 compatibility"), ONE_DASH },
26877298Sobrien  { {"emit-relocs", no_argument, NULL, 'q'},
269218822Sdim    'q', NULL, "Generate relocations in final output", TWO_DASHES },
270130561Sobrien  { {"relocatable", no_argument, NULL, 'r'},
271218822Sdim    'r', NULL, N_("Generate relocatable output"), TWO_DASHES },
27233965Sjdp  { {NULL, no_argument, NULL, '\0'},
273218822Sdim    'i', NULL, NULL, ONE_DASH },
27433965Sjdp  { {"just-symbols", required_argument, NULL, 'R'},
275218822Sdim    'R', N_("FILE"), N_("Just link symbols (if directory, same as --rpath)"),
276218822Sdim    TWO_DASHES },
27733965Sjdp  { {"strip-all", no_argument, NULL, 's'},
278218822Sdim    's', NULL, N_("Strip all symbols"), TWO_DASHES },
27933965Sjdp  { {"strip-debug", no_argument, NULL, 'S'},
280218822Sdim    'S', NULL, N_("Strip debugging symbols"), TWO_DASHES },
281130561Sobrien  { {"strip-discarded", no_argument, NULL, OPTION_STRIP_DISCARDED},
282218822Sdim    '\0', NULL, N_("Strip symbols in discarded sections"), TWO_DASHES },
283130561Sobrien  { {"no-strip-discarded", no_argument, NULL, OPTION_NO_STRIP_DISCARDED},
284218822Sdim    '\0', NULL, N_("Do not strip symbols in discarded sections"), TWO_DASHES },
28533965Sjdp  { {"trace", no_argument, NULL, 't'},
286218822Sdim    't', NULL, N_("Trace file opens"), TWO_DASHES },
28733965Sjdp  { {"script", required_argument, NULL, 'T'},
288218822Sdim    'T', N_("FILE"), N_("Read linker script"), TWO_DASHES },
289218822Sdim  { {"default-script", required_argument, NULL, OPTION_DEFAULT_SCRIPT},
290218822Sdim    '\0', N_("FILE"), N_("Read default linker script"), TWO_DASHES },
291218822Sdim  { {"dT", required_argument, NULL, OPTION_DEFAULT_SCRIPT},
292218822Sdim    '\0', NULL, NULL, ONE_DASH },
29333965Sjdp  { {"undefined", required_argument, NULL, 'u'},
294218822Sdim    'u', N_("SYMBOL"), N_("Start with undefined reference to SYMBOL"),
295218822Sdim    TWO_DASHES },
29677298Sobrien  { {"unique", optional_argument, NULL, OPTION_UNIQUE},
297218822Sdim    '\0', N_("[=SECTION]"),
298218822Sdim    N_("Don't merge input [SECTION | orphan] sections"), TWO_DASHES },
29960484Sobrien  { {"Ur", no_argument, NULL, OPTION_UR},
300218822Sdim    '\0', NULL, N_("Build global constructor/destructor tables"), ONE_DASH },
30133965Sjdp  { {"version", no_argument, NULL, OPTION_VERSION},
302218822Sdim    'v', NULL, N_("Print version information"), TWO_DASHES },
30333965Sjdp  { {NULL, no_argument, NULL, '\0'},
304218822Sdim    'V', NULL, N_("Print version and emulation information"), ONE_DASH },
30533965Sjdp  { {"discard-all", no_argument, NULL, 'x'},
306218822Sdim    'x', NULL, N_("Discard all local symbols"), TWO_DASHES },
30733965Sjdp  { {"discard-locals", no_argument, NULL, 'X'},
308218822Sdim    'X', NULL, N_("Discard temporary local symbols (default)"), TWO_DASHES },
30989857Sobrien  { {"discard-none", no_argument, NULL, OPTION_DISCARD_NONE},
310218822Sdim    '\0', NULL, N_("Don't discard any local symbols"), TWO_DASHES },
31133965Sjdp  { {"trace-symbol", required_argument, NULL, 'y'},
312218822Sdim    'y', N_("SYMBOL"), N_("Trace mentions of SYMBOL"), TWO_DASHES },
31333965Sjdp  { {NULL, required_argument, NULL, '\0'},
314218822Sdim    'Y', N_("PATH"), N_("Default search path for Solaris compatibility"),
315218822Sdim    ONE_DASH },
31633965Sjdp  { {"start-group", no_argument, NULL, '('},
317218822Sdim    '(', NULL, N_("Start a group"), TWO_DASHES },
31833965Sjdp  { {"end-group", no_argument, NULL, ')'},
319218822Sdim    ')', NULL, N_("End a group"), TWO_DASHES },
320218822Sdim  { {"accept-unknown-input-arch", no_argument, NULL,
321218822Sdim     OPTION_ACCEPT_UNKNOWN_INPUT_ARCH},
322218822Sdim    '\0', NULL,
323218822Sdim    N_("Accept input files whose architecture cannot be determined"),
324218822Sdim    TWO_DASHES },
325218822Sdim  { {"no-accept-unknown-input-arch", no_argument, NULL,
326218822Sdim     OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH},
327218822Sdim    '\0', NULL, N_("Reject input files whose architecture is unknown"),
328218822Sdim    TWO_DASHES },
329218822Sdim  { {"add-needed", no_argument, NULL, OPTION_ADD_NEEDED},
330218822Sdim    '\0', NULL, N_("Set DT_NEEDED tags for DT_NEEDED entries in\n"
331218822Sdim		   "\t\t\t\tfollowing dynamic libs"), TWO_DASHES },
332218822Sdim  { {"no-add-needed", no_argument, NULL, OPTION_NO_ADD_NEEDED},
333218822Sdim    '\0', NULL, N_("Do not set DT_NEEDED tags for DT_NEEDED entries\n"
334218822Sdim		   "\t\t\t\tin following dynamic libs"), TWO_DASHES },
335218822Sdim  { {"as-needed", no_argument, NULL, OPTION_AS_NEEDED},
336218822Sdim    '\0', NULL, N_("Only set DT_NEEDED for following dynamic libs if used"),
337218822Sdim    TWO_DASHES },
338218822Sdim  { {"no-as-needed", no_argument, NULL, OPTION_NO_AS_NEEDED},
339218822Sdim    '\0', NULL, N_("Always set DT_NEEDED for following dynamic libs"),
340218822Sdim    TWO_DASHES },
34133965Sjdp  { {"assert", required_argument, NULL, OPTION_ASSERT},
342218822Sdim    '\0', N_("KEYWORD"), N_("Ignored for SunOS compatibility"), ONE_DASH },
34333965Sjdp  { {"Bdynamic", no_argument, NULL, OPTION_CALL_SHARED},
344218822Sdim    '\0', NULL, N_("Link against shared libraries"), ONE_DASH },
34533965Sjdp  { {"dy", no_argument, NULL, OPTION_CALL_SHARED},
346218822Sdim    '\0', NULL, NULL, ONE_DASH },
34733965Sjdp  { {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
348218822Sdim    '\0', NULL, NULL, ONE_DASH },
34933965Sjdp  { {"Bstatic", no_argument, NULL, OPTION_NON_SHARED},
350218822Sdim    '\0', NULL, N_("Do not link against shared libraries"), ONE_DASH },
35133965Sjdp  { {"dn", no_argument, NULL, OPTION_NON_SHARED},
352218822Sdim    '\0', NULL, NULL, ONE_DASH },
35333965Sjdp  { {"non_shared", no_argument, NULL, OPTION_NON_SHARED},
354218822Sdim    '\0', NULL, NULL, ONE_DASH },
35533965Sjdp  { {"static", no_argument, NULL, OPTION_NON_SHARED},
356218822Sdim    '\0', NULL, NULL, ONE_DASH },
35733965Sjdp  { {"Bsymbolic", no_argument, NULL, OPTION_SYMBOLIC},
358218822Sdim    '\0', NULL, N_("Bind global references locally"), ONE_DASH },
359218822Sdim  { {"Bsymbolic-functions", no_argument, NULL, OPTION_SYMBOLIC_FUNCTIONS},
360218822Sdim    '\0', NULL, N_("Bind global function references locally"), ONE_DASH },
36160484Sobrien  { {"check-sections", no_argument, NULL, OPTION_CHECK_SECTIONS},
362218822Sdim    '\0', NULL, N_("Check section addresses for overlaps (default)"),
363218822Sdim    TWO_DASHES },
36460484Sobrien  { {"no-check-sections", no_argument, NULL, OPTION_NO_CHECK_SECTIONS},
365218822Sdim    '\0', NULL, N_("Do not check section addresses for overlaps"),
366218822Sdim    TWO_DASHES },
36733965Sjdp  { {"cref", no_argument, NULL, OPTION_CREF},
368218822Sdim    '\0', NULL, N_("Output cross reference table"), TWO_DASHES },
36933965Sjdp  { {"defsym", required_argument, NULL, OPTION_DEFSYM},
370218822Sdim    '\0', N_("SYMBOL=EXPRESSION"), N_("Define a symbol"), TWO_DASHES },
37177298Sobrien  { {"demangle", optional_argument, NULL, OPTION_DEMANGLE},
372218822Sdim    '\0', N_("[=STYLE]"), N_("Demangle symbol names [using STYLE]"),
373218822Sdim    TWO_DASHES },
37433965Sjdp  { {"embedded-relocs", no_argument, NULL, OPTION_EMBEDDED_RELOCS},
375218822Sdim    '\0', NULL, N_("Generate embedded relocs"), TWO_DASHES},
376218822Sdim  { {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL},
377218822Sdim    '\0', NULL, N_("Treat warnings as errors"),
378218822Sdim    TWO_DASHES },
379306136Semaste  { {"no-fatal-warnings", no_argument, NULL, OPTION_NO_WARN_FATAL},
380306136Semaste    '\0', NULL, N_("Don't treat warnings as errors"),
381306136Semaste    TWO_DASHES },
38260484Sobrien  { {"fini", required_argument, NULL, OPTION_FINI},
383218822Sdim    '\0', N_("SYMBOL"), N_("Call SYMBOL at unload-time"), ONE_DASH },
38433965Sjdp  { {"force-exe-suffix", no_argument, NULL, OPTION_FORCE_EXE_SUFFIX},
385218822Sdim    '\0', NULL, N_("Force generation of file with .exe suffix"), TWO_DASHES},
38660484Sobrien  { {"gc-sections", no_argument, NULL, OPTION_GC_SECTIONS},
387218822Sdim    '\0', NULL, N_("Remove unused sections (on some targets)"),
388218822Sdim    TWO_DASHES },
38960484Sobrien  { {"no-gc-sections", no_argument, NULL, OPTION_NO_GC_SECTIONS},
390218822Sdim    '\0', NULL, N_("Don't remove unused sections (default)"),
391218822Sdim    TWO_DASHES },
392218822Sdim  { {"print-gc-sections", no_argument, NULL, OPTION_PRINT_GC_SECTIONS},
393218822Sdim    '\0', NULL, N_("List removed unused sections on stderr"),
394218822Sdim    TWO_DASHES },
395218822Sdim  { {"no-print-gc-sections", no_argument, NULL, OPTION_NO_PRINT_GC_SECTIONS},
396218822Sdim    '\0', NULL, N_("Do not list removed unused sections"),
397218822Sdim    TWO_DASHES },
398218822Sdim  { {"hash-size=<NUMBER>", required_argument, NULL, OPTION_HASH_SIZE},
399218822Sdim    '\0', NULL, N_("Set default hash table size close to <NUMBER>"),
400218822Sdim    TWO_DASHES },
40133965Sjdp  { {"help", no_argument, NULL, OPTION_HELP},
402218822Sdim    '\0', NULL, N_("Print option help"), TWO_DASHES },
40360484Sobrien  { {"init", required_argument, NULL, OPTION_INIT},
404218822Sdim    '\0', N_("SYMBOL"), N_("Call SYMBOL at load-time"), ONE_DASH },
40533965Sjdp  { {"Map", required_argument, NULL, OPTION_MAP},
406218822Sdim    '\0', N_("FILE"), N_("Write a map file"), ONE_DASH },
40789857Sobrien  { {"no-define-common", no_argument, NULL, OPTION_NO_DEFINE_COMMON},
408218822Sdim    '\0', NULL, N_("Do not define Common storage"), TWO_DASHES },
40960484Sobrien  { {"no-demangle", no_argument, NULL, OPTION_NO_DEMANGLE },
410218822Sdim    '\0', NULL, N_("Do not demangle symbol names"), TWO_DASHES },
41133965Sjdp  { {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY},
412218822Sdim    '\0', NULL, N_("Use less memory and more disk I/O"), TWO_DASHES },
41360484Sobrien  { {"no-undefined", no_argument, NULL, OPTION_NO_UNDEFINED},
414218822Sdim    '\0', NULL, N_("Do not allow unresolved references in object files"),
415218822Sdim    TWO_DASHES },
41677298Sobrien  { {"allow-shlib-undefined", no_argument, NULL, OPTION_ALLOW_SHLIB_UNDEFINED},
417218822Sdim    '\0', NULL, N_("Allow unresolved references in shared libaries"),
418218822Sdim    TWO_DASHES },
419218822Sdim  { {"no-allow-shlib-undefined", no_argument, NULL,
420218822Sdim     OPTION_NO_ALLOW_SHLIB_UNDEFINED},
421218822Sdim    '\0', NULL, N_("Do not allow unresolved references in shared libs"),
422218822Sdim    TWO_DASHES },
423218822Sdim  { {"allow-multiple-definition", no_argument, NULL,
424218822Sdim     OPTION_ALLOW_MULTIPLE_DEFINITION},
425218822Sdim    '\0', NULL, N_("Allow multiple definitions"), TWO_DASHES },
426104834Sobrien  { {"no-undefined-version", no_argument, NULL, OPTION_NO_UNDEFINED_VERSION},
427218822Sdim    '\0', NULL, N_("Disallow undefined version"), TWO_DASHES },
428218822Sdim  { {"default-symver", no_argument, NULL, OPTION_DEFAULT_SYMVER},
429218822Sdim    '\0', NULL, N_("Create default symbol version"), TWO_DASHES },
430218822Sdim  { {"default-imported-symver", no_argument, NULL,
431218822Sdim      OPTION_DEFAULT_IMPORTED_SYMVER},
432218822Sdim    '\0', NULL, N_("Create default symbol version for imported symbols"),
433218822Sdim    TWO_DASHES },
43438889Sjdp  { {"no-warn-mismatch", no_argument, NULL, OPTION_NO_WARN_MISMATCH},
435218822Sdim    '\0', NULL, N_("Don't warn about mismatched input files"), TWO_DASHES},
436218822Sdim  { {"no-warn-search-mismatch", no_argument, NULL,
437218822Sdim     OPTION_NO_WARN_SEARCH_MISMATCH},
438218822Sdim    '\0', NULL, N_("Don't warn on finding an incompatible library"),
439218822Sdim    TWO_DASHES},
44033965Sjdp  { {"no-whole-archive", no_argument, NULL, OPTION_NO_WHOLE_ARCHIVE},
441218822Sdim    '\0', NULL, N_("Turn off --whole-archive"), TWO_DASHES },
44233965Sjdp  { {"noinhibit-exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
443218822Sdim    '\0', NULL, N_("Create an output file even if errors occur"),
444218822Sdim    TWO_DASHES },
44533965Sjdp  { {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
446218822Sdim    '\0', NULL, NULL, NO_HELP },
44789857Sobrien  { {"nostdlib", no_argument, NULL, OPTION_NOSTDLIB},
448218822Sdim    '\0', NULL, N_("Only use library directories specified on\n"
449218822Sdim		   "\t\t\t\tthe command line"), ONE_DASH },
45033965Sjdp  { {"oformat", required_argument, NULL, OPTION_OFORMAT},
451218822Sdim    '\0', N_("TARGET"), N_("Specify target of output file"),
452218822Sdim    EXACTLY_TWO_DASHES },
45333965Sjdp  { {"qmagic", no_argument, NULL, OPTION_IGNORE},
454218822Sdim    '\0', NULL, N_("Ignored for Linux compatibility"), ONE_DASH },
455218822Sdim  { {"reduce-memory-overheads", no_argument, NULL,
456218822Sdim     OPTION_REDUCE_MEMORY_OVERHEADS},
457218822Sdim    '\0', NULL, N_("Reduce memory overheads, possibly taking much longer"),
458218822Sdim    TWO_DASHES },
45933965Sjdp  { {"relax", no_argument, NULL, OPTION_RELAX},
460218822Sdim    '\0', NULL, N_("Relax branches on certain targets"), TWO_DASHES },
46133965Sjdp  { {"retain-symbols-file", required_argument, NULL,
462218822Sdim     OPTION_RETAIN_SYMBOLS_FILE},
463218822Sdim    '\0', N_("FILE"), N_("Keep only symbols listed in FILE"), TWO_DASHES },
46433965Sjdp  { {"rpath", required_argument, NULL, OPTION_RPATH},
465218822Sdim    '\0', N_("PATH"), N_("Set runtime shared library search path"), ONE_DASH },
46633965Sjdp  { {"rpath-link", required_argument, NULL, OPTION_RPATH_LINK},
467218822Sdim    '\0', N_("PATH"), N_("Set link time shared library search path"),
468218822Sdim    ONE_DASH },
46933965Sjdp  { {"shared", no_argument, NULL, OPTION_SHARED},
470218822Sdim    '\0', NULL, N_("Create a shared library"), ONE_DASH },
47133965Sjdp  { {"Bshareable", no_argument, NULL, OPTION_SHARED }, /* FreeBSD.  */
472218822Sdim    '\0', NULL, NULL, ONE_DASH },
473130561Sobrien  { {"pie", no_argument, NULL, OPTION_PIE},
474218822Sdim    '\0', NULL, N_("Create a position independent executable"), ONE_DASH },
475130561Sobrien  { {"pic-executable", no_argument, NULL, OPTION_PIE},
476218822Sdim    '\0', NULL, NULL, TWO_DASHES },
47733965Sjdp  { {"sort-common", no_argument, NULL, OPTION_SORT_COMMON},
478218822Sdim    '\0', NULL, N_("Sort common symbols by size"), TWO_DASHES },
47933965Sjdp  { {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
480218822Sdim    '\0', NULL, NULL, NO_HELP },
481218822Sdim  { {"sort-section", required_argument, NULL, OPTION_SORT_SECTION},
482218822Sdim    '\0', N_("name|alignment"),
483218822Sdim    N_("Sort sections by name or maximum alignment"), TWO_DASHES },
48489857Sobrien  { {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_DYNAMIC_TAGS},
485218822Sdim    '\0', N_("COUNT"), N_("How many tags to reserve in .dynamic section"),
486218822Sdim    TWO_DASHES },
48777298Sobrien  { {"split-by-file", optional_argument, NULL, OPTION_SPLIT_BY_FILE},
488218822Sdim    '\0', N_("[=SIZE]"), N_("Split output sections every SIZE octets"),
489218822Sdim    TWO_DASHES },
49077298Sobrien  { {"split-by-reloc", optional_argument, NULL, OPTION_SPLIT_BY_RELOC},
491218822Sdim    '\0', N_("[=COUNT]"), N_("Split output sections every COUNT relocs"),
492218822Sdim    TWO_DASHES },
49333965Sjdp  { {"stats", no_argument, NULL, OPTION_STATS},
494218822Sdim    '\0', NULL, N_("Print memory usage statistics"), TWO_DASHES },
49577298Sobrien  { {"target-help", no_argument, NULL, OPTION_TARGET_HELP},
496218822Sdim    '\0', NULL, N_("Display target specific options"), TWO_DASHES },
49738889Sjdp  { {"task-link", required_argument, NULL, OPTION_TASK_LINK},
498218822Sdim    '\0', N_("SYMBOL"), N_("Do task level linking"), TWO_DASHES },
49933965Sjdp  { {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT},
500218822Sdim    '\0', NULL, N_("Use same format as native linker"), TWO_DASHES },
50177298Sobrien  { {"section-start", required_argument, NULL, OPTION_SECTION_START},
502218822Sdim    '\0', N_("SECTION=ADDRESS"), N_("Set address of named section"),
503218822Sdim    TWO_DASHES },
50433965Sjdp  { {"Tbss", required_argument, NULL, OPTION_TBSS},
505218822Sdim    '\0', N_("ADDRESS"), N_("Set address of .bss section"), ONE_DASH },
50633965Sjdp  { {"Tdata", required_argument, NULL, OPTION_TDATA},
507218822Sdim    '\0', N_("ADDRESS"), N_("Set address of .data section"), ONE_DASH },
50833965Sjdp  { {"Ttext", required_argument, NULL, OPTION_TTEXT},
509218822Sdim    '\0', N_("ADDRESS"), N_("Set address of .text section"), ONE_DASH },
510218822Sdim  { {"unresolved-symbols=<method>", required_argument, NULL,
511218822Sdim     OPTION_UNRESOLVED_SYMBOLS},
512218822Sdim    '\0', NULL, N_("How to handle unresolved symbols.  <method> is:\n"
513218822Sdim		   "\t\t\t\tignore-all, report-all, ignore-in-object-files,\n"
514218822Sdim		   "\t\t\t\tignore-in-shared-libs"), TWO_DASHES },
51533965Sjdp  { {"verbose", no_argument, NULL, OPTION_VERBOSE},
516218822Sdim    '\0', NULL, N_("Output lots of information during link"), TWO_DASHES },
51733965Sjdp  { {"dll-verbose", no_argument, NULL, OPTION_VERBOSE}, /* Linux.  */
518218822Sdim    '\0', NULL, NULL, NO_HELP },
51933965Sjdp  { {"version-script", required_argument, NULL, OPTION_VERSION_SCRIPT },
520218822Sdim    '\0', N_("FILE"), N_("Read version information script"), TWO_DASHES },
52160484Sobrien  { {"version-exports-section", required_argument, NULL,
52260484Sobrien     OPTION_VERSION_EXPORTS_SECTION },
523218822Sdim    '\0', N_("SYMBOL"), N_("Take export symbols list from .exports, using\n"
524218822Sdim			   "\t\t\t\tSYMBOL as the version."), TWO_DASHES },
525218822Sdim  { {"dynamic-list-data", no_argument, NULL, OPTION_DYNAMIC_LIST_DATA},
526218822Sdim    '\0', NULL, N_("Add data symbols to dynamic list"), TWO_DASHES },
527218822Sdim  { {"dynamic-list-cpp-new", no_argument, NULL, OPTION_DYNAMIC_LIST_CPP_NEW},
528218822Sdim    '\0', NULL, N_("Use C++ operator new/delete dynamic list"), TWO_DASHES },
529218822Sdim  { {"dynamic-list-cpp-typeinfo", no_argument, NULL, OPTION_DYNAMIC_LIST_CPP_TYPEINFO},
530218822Sdim    '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },
531218822Sdim  { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},
532218822Sdim    '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },
53333965Sjdp  { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
534218822Sdim    '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },
53533965Sjdp  { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},
536218822Sdim    '\0', NULL, N_("Warn if global constructors/destructors are seen"),
537218822Sdim    TWO_DASHES },
53833965Sjdp  { {"warn-multiple-gp", no_argument, NULL, OPTION_WARN_MULTIPLE_GP},
539218822Sdim    '\0', NULL, N_("Warn if the multiple GP values are used"), TWO_DASHES },
54033965Sjdp  { {"warn-once", no_argument, NULL, OPTION_WARN_ONCE},
541218822Sdim    '\0', NULL, N_("Warn only once per undefined symbol"), TWO_DASHES },
54233965Sjdp  { {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN},
543218822Sdim    '\0', NULL, N_("Warn if start of section changes due to alignment"),
544218822Sdim    TWO_DASHES },
545218822Sdim  { {"warn-shared-textrel", no_argument, NULL, OPTION_WARN_SHARED_TEXTREL},
546218822Sdim    '\0', NULL, N_("Warn if shared object has DT_TEXTREL"),
547218822Sdim    TWO_DASHES },
548218822Sdim  { {"warn-unresolved-symbols", no_argument, NULL,
549218822Sdim     OPTION_WARN_UNRESOLVED_SYMBOLS},
550130561Sobrien    '\0', NULL, N_("Report unresolved symbols as warnings"), TWO_DASHES },
551218822Sdim  { {"error-unresolved-symbols", no_argument, NULL,
552218822Sdim     OPTION_ERROR_UNRESOLVED_SYMBOLS},
553130561Sobrien    '\0', NULL, N_("Report unresolved symbols as errors"), TWO_DASHES },
55433965Sjdp  { {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE},
555218822Sdim    '\0', NULL, N_("Include all objects from following archives"),
556218822Sdim    TWO_DASHES },
55733965Sjdp  { {"wrap", required_argument, NULL, OPTION_WRAP},
558218822Sdim    '\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES },
55933965Sjdp};
56033965Sjdp
56177298Sobrien#define OPTION_COUNT ARRAY_SIZE (ld_options)
56233965Sjdp
56333965Sjdpvoid
564130561Sobrienparse_args (unsigned argc, char **argv)
56533965Sjdp{
56677298Sobrien  unsigned i;
56777298Sobrien  int is, il, irl;
56833965Sjdp  int ingroup = 0;
56933965Sjdp  char *default_dirlist = NULL;
570130561Sobrien  char *shortopts;
571130561Sobrien  struct option *longopts;
572130561Sobrien  struct option *really_longopts;
57338889Sjdp  int last_optind;
574130561Sobrien  enum report_method how_to_report_unresolved_symbols = RM_GENERATE_ERROR;
575306136Semaste  int no_fatal_warnings = FALSE;
57633965Sjdp
577130561Sobrien  shortopts = xmalloc (OPTION_COUNT * 3 + 2);
578130561Sobrien  longopts = xmalloc (sizeof (*longopts) * (OPTION_COUNT + 1));
579130561Sobrien  really_longopts = xmalloc (sizeof (*really_longopts) * (OPTION_COUNT + 1));
580130561Sobrien
58133965Sjdp  /* Starting the short option string with '-' is for programs that
58233965Sjdp     expect options and other ARGV-elements in any order and that care about
58333965Sjdp     the ordering of the two.  We describe each non-option ARGV-element
58433965Sjdp     as if it were the argument of an option with character code 1.  */
58533965Sjdp  shortopts[0] = '-';
58633965Sjdp  is = 1;
58733965Sjdp  il = 0;
58877298Sobrien  irl = 0;
58933965Sjdp  for (i = 0; i < OPTION_COUNT; i++)
59033965Sjdp    {
59133965Sjdp      if (ld_options[i].shortopt != '\0')
59233965Sjdp	{
59333965Sjdp	  shortopts[is] = ld_options[i].shortopt;
59433965Sjdp	  ++is;
59533965Sjdp	  if (ld_options[i].opt.has_arg == required_argument
59633965Sjdp	      || ld_options[i].opt.has_arg == optional_argument)
59733965Sjdp	    {
59833965Sjdp	      shortopts[is] = ':';
59933965Sjdp	      ++is;
60033965Sjdp	      if (ld_options[i].opt.has_arg == optional_argument)
60133965Sjdp		{
60233965Sjdp		  shortopts[is] = ':';
60333965Sjdp		  ++is;
60433965Sjdp		}
60533965Sjdp	    }
60633965Sjdp	}
60733965Sjdp      if (ld_options[i].opt.name != NULL)
60833965Sjdp	{
60977298Sobrien	  if (ld_options[i].control == EXACTLY_TWO_DASHES)
61077298Sobrien	    {
61177298Sobrien	      really_longopts[irl] = ld_options[i].opt;
61277298Sobrien	      ++irl;
61377298Sobrien	    }
61477298Sobrien	  else
61577298Sobrien	    {
61677298Sobrien	      longopts[il] = ld_options[i].opt;
61777298Sobrien	      ++il;
61877298Sobrien	    }
61933965Sjdp	}
62033965Sjdp    }
62133965Sjdp  shortopts[is] = '\0';
62233965Sjdp  longopts[il].name = NULL;
62377298Sobrien  really_longopts[irl].name = NULL;
62433965Sjdp
625130561Sobrien  ldemul_add_options (is, &shortopts, il, &longopts, irl, &really_longopts);
626130561Sobrien
62733965Sjdp  /* The -G option is ambiguous on different platforms.  Sometimes it
62833965Sjdp     specifies the largest data size to put into the small data
62933965Sjdp     section.  Sometimes it is equivalent to --shared.  Unfortunately,
63033965Sjdp     the first form takes an argument, while the second does not.
63133965Sjdp
63233965Sjdp     We need to permit the --shared form because on some platforms,
63333965Sjdp     such as Solaris, gcc -shared will pass -G to the linker.
63433965Sjdp
63533965Sjdp     To permit either usage, we look through the argument list.  If we
63633965Sjdp     find -G not followed by a number, we change it into --shared.
63733965Sjdp     This will work for most normal cases.  */
63833965Sjdp  for (i = 1; i < argc; i++)
63933965Sjdp    if (strcmp (argv[i], "-G") == 0
64033965Sjdp	&& (i + 1 >= argc
64189857Sobrien	    || ! ISDIGIT (argv[i + 1][0])))
64233965Sjdp      argv[i] = (char *) "--shared";
64333965Sjdp
64460484Sobrien  /* Because we permit long options to start with a single dash, and
64560484Sobrien     we have a --library option, and the -l option is conventionally
64660484Sobrien     used with an immediately following argument, we can have bad
64760484Sobrien     results if somebody tries to use -l with a library whose name
64860484Sobrien     happens to start with "ibrary", as in -li.  We avoid problems by
64960484Sobrien     simply turning -l into --library.  This means that users will
65060484Sobrien     have to use two dashes in order to use --library, which is OK
65160484Sobrien     since that's how it is documented.
65260484Sobrien
65360484Sobrien     FIXME: It's possible that this problem can arise for other short
65460484Sobrien     options as well, although the user does always have the recourse
65560484Sobrien     of adding a space between the option and the argument.  */
65660484Sobrien  for (i = 1; i < argc; i++)
65760484Sobrien    {
65860484Sobrien      if (argv[i][0] == '-'
65960484Sobrien	  && argv[i][1] == 'l'
66060484Sobrien	  && argv[i][2] != '\0')
66160484Sobrien	{
66260484Sobrien	  char *n;
66360484Sobrien
664130561Sobrien	  n = xmalloc (strlen (argv[i]) + 20);
66560484Sobrien	  sprintf (n, "--library=%s", argv[i] + 2);
66660484Sobrien	  argv[i] = n;
66760484Sobrien	}
66860484Sobrien    }
66960484Sobrien
67038889Sjdp  last_optind = -1;
67133965Sjdp  while (1)
67233965Sjdp    {
67333965Sjdp      int longind;
67433965Sjdp      int optc;
67533965Sjdp
67638889Sjdp      /* Using last_optind lets us avoid calling ldemul_parse_args
67738889Sjdp	 multiple times on a single option, which would lead to
67838889Sjdp	 confusion in the internal static variables maintained by
67938889Sjdp	 getopt.  This could otherwise happen for an argument like
68038889Sjdp	 -nx, in which the -n is parsed as a single option, and we
68138889Sjdp	 loop around to pick up the -x.  */
68238889Sjdp      if (optind != last_optind)
68389857Sobrien	if (ldemul_parse_args (argc, argv))
68489857Sobrien	  continue;
68533965Sjdp
68660484Sobrien      /* getopt_long_only is like getopt_long, but '-' as well as '--'
68760484Sobrien	 can indicate a long option.  */
68877298Sobrien      opterr = 0;
68989857Sobrien      last_optind = optind;
69033965Sjdp      optc = getopt_long_only (argc, argv, shortopts, longopts, &longind);
69177298Sobrien      if (optc == '?')
69277298Sobrien	{
69389857Sobrien	  optind = last_optind;
69489857Sobrien	  optc = getopt_long (argc, argv, "-", really_longopts, &longind);
69577298Sobrien	}
69633965Sjdp
697130561Sobrien      if (ldemul_handle_option (optc))
698130561Sobrien	continue;
699130561Sobrien
70033965Sjdp      if (optc == -1)
70133965Sjdp	break;
70277298Sobrien
70333965Sjdp      switch (optc)
70433965Sjdp	{
70577298Sobrien	case '?':
70689857Sobrien	  einfo (_("%P: unrecognized option '%s'\n"), argv[last_optind]);
707218822Sdim	  /* Fall through.  */
708218822Sdim
70933965Sjdp	default:
71089857Sobrien	  einfo (_("%P%F: use the --help option for usage information\n"));
71189857Sobrien
71233965Sjdp	case 1:			/* File name.  */
713130561Sobrien	  lang_add_input_file (optarg, lang_input_file_is_file_enum, NULL);
71433965Sjdp	  break;
71533965Sjdp
71633965Sjdp	case OPTION_IGNORE:
71733965Sjdp	  break;
71833965Sjdp	case 'a':
71933965Sjdp	  /* For HP/UX compatibility.  Actually -a shared should mean
720130561Sobrien	     ``use only shared libraries'' but, then, we don't
721130561Sobrien	     currently support shared libraries on HP/UX anyhow.  */
72233965Sjdp	  if (strcmp (optarg, "archive") == 0)
723130561Sobrien	    config.dynamic_link = FALSE;
72433965Sjdp	  else if (strcmp (optarg, "shared") == 0
72533965Sjdp		   || strcmp (optarg, "default") == 0)
726130561Sobrien	    config.dynamic_link = TRUE;
72733965Sjdp	  else
72860484Sobrien	    einfo (_("%P%F: unrecognized -a option `%s'\n"), optarg);
72933965Sjdp	  break;
73033965Sjdp	case OPTION_ASSERT:
73133965Sjdp	  /* FIXME: We just ignore these, but we should handle them.  */
73233965Sjdp	  if (strcmp (optarg, "definitions") == 0)
73333965Sjdp	    ;
73433965Sjdp	  else if (strcmp (optarg, "nodefinitions") == 0)
73533965Sjdp	    ;
73633965Sjdp	  else if (strcmp (optarg, "nosymbolic") == 0)
73733965Sjdp	    ;
73833965Sjdp	  else if (strcmp (optarg, "pure-text") == 0)
73933965Sjdp	    ;
74033965Sjdp	  else
74160484Sobrien	    einfo (_("%P%F: unrecognized -assert option `%s'\n"), optarg);
74233965Sjdp	  break;
74333965Sjdp	case 'A':
74433965Sjdp	  ldfile_add_arch (optarg);
74533965Sjdp	  break;
74633965Sjdp	case 'b':
74733965Sjdp	  lang_add_target (optarg);
74833965Sjdp	  break;
74933965Sjdp	case 'c':
75033965Sjdp	  ldfile_open_command_file (optarg);
75133965Sjdp	  parser_input = input_mri_script;
75233965Sjdp	  yyparse ();
75333965Sjdp	  break;
75433965Sjdp	case OPTION_CALL_SHARED:
755130561Sobrien	  config.dynamic_link = TRUE;
75633965Sjdp	  break;
75733965Sjdp	case OPTION_NON_SHARED:
758130561Sobrien	  config.dynamic_link = FALSE;
75933965Sjdp	  break;
76033965Sjdp	case OPTION_CREF:
761130561Sobrien	  command_line.cref = TRUE;
762130561Sobrien	  link_info.notice_all = TRUE;
76333965Sjdp	  break;
76433965Sjdp	case 'd':
765130561Sobrien	  command_line.force_common_definition = TRUE;
76633965Sjdp	  break;
76733965Sjdp	case OPTION_DEFSYM:
76833965Sjdp	  lex_string = optarg;
76933965Sjdp	  lex_redirect (optarg);
77033965Sjdp	  parser_input = input_defsym;
77133965Sjdp	  parsing_defsym = 1;
77233965Sjdp	  yyparse ();
77333965Sjdp	  parsing_defsym = 0;
77433965Sjdp	  lex_string = NULL;
77533965Sjdp	  break;
77660484Sobrien	case OPTION_DEMANGLE:
777130561Sobrien	  demangling = TRUE;
77877298Sobrien	  if (optarg != NULL)
77977298Sobrien	    {
78077298Sobrien	      enum demangling_styles style;
78177298Sobrien
78277298Sobrien	      style = cplus_demangle_name_to_style (optarg);
78377298Sobrien	      if (style == unknown_demangling)
78477298Sobrien		einfo (_("%F%P: unknown demangling style `%s'"),
78577298Sobrien		       optarg);
78677298Sobrien
78777298Sobrien	      cplus_demangle_set_style (style);
78877298Sobrien	    }
78960484Sobrien	  break;
79089857Sobrien	case 'I':		/* Used on Solaris.  */
79133965Sjdp	case OPTION_DYNAMIC_LINKER:
79233965Sjdp	  command_line.interpreter = optarg;
79333965Sjdp	  break;
794218822Sdim	case OPTION_SYSROOT:
795218822Sdim	  /* Already handled in ldmain.c.  */
796218822Sdim	  break;
79733965Sjdp	case OPTION_EB:
79833965Sjdp	  command_line.endian = ENDIAN_BIG;
79933965Sjdp	  break;
80033965Sjdp	case OPTION_EL:
80133965Sjdp	  command_line.endian = ENDIAN_LITTLE;
80233965Sjdp	  break;
80333965Sjdp	case OPTION_EMBEDDED_RELOCS:
804130561Sobrien	  command_line.embedded_relocs = TRUE;
80533965Sjdp	  break;
80633965Sjdp	case OPTION_EXPORT_DYNAMIC:
80733965Sjdp	case 'E': /* HP/UX compatibility.  */
808130561Sobrien	  link_info.export_dynamic = TRUE;
80933965Sjdp	  break;
81033965Sjdp	case 'e':
811130561Sobrien	  lang_add_entry (optarg, TRUE);
81233965Sjdp	  break;
81333965Sjdp	case 'f':
81433965Sjdp	  if (command_line.auxiliary_filters == NULL)
81533965Sjdp	    {
816130561Sobrien	      command_line.auxiliary_filters = xmalloc (2 * sizeof (char *));
81733965Sjdp	      command_line.auxiliary_filters[0] = optarg;
81833965Sjdp	      command_line.auxiliary_filters[1] = NULL;
81933965Sjdp	    }
82033965Sjdp	  else
82133965Sjdp	    {
82233965Sjdp	      int c;
82333965Sjdp	      char **p;
82433965Sjdp
82533965Sjdp	      c = 0;
82633965Sjdp	      for (p = command_line.auxiliary_filters; *p != NULL; p++)
82733965Sjdp		++c;
828130561Sobrien	      command_line.auxiliary_filters
829130561Sobrien		= xrealloc (command_line.auxiliary_filters,
830130561Sobrien			    (c + 2) * sizeof (char *));
83133965Sjdp	      command_line.auxiliary_filters[c] = optarg;
83233965Sjdp	      command_line.auxiliary_filters[c + 1] = NULL;
83333965Sjdp	    }
83433965Sjdp	  break;
83533965Sjdp	case 'F':
83633965Sjdp	  command_line.filter_shlib = optarg;
83733965Sjdp	  break;
83833965Sjdp	case OPTION_FORCE_EXE_SUFFIX:
839130561Sobrien	  command_line.force_exe_suffix = TRUE;
84033965Sjdp	  break;
84133965Sjdp	case 'G':
84233965Sjdp	  {
84333965Sjdp	    char *end;
84433965Sjdp	    g_switch_value = strtoul (optarg, &end, 0);
84533965Sjdp	    if (*end)
84660484Sobrien	      einfo (_("%P%F: invalid number `%s'\n"), optarg);
84733965Sjdp	  }
84833965Sjdp	  break;
84933965Sjdp	case 'g':
85033965Sjdp	  /* Ignore.  */
85133965Sjdp	  break;
85260484Sobrien	case OPTION_GC_SECTIONS:
853218822Sdim	  link_info.gc_sections = TRUE;
85460484Sobrien	  break;
855218822Sdim	case OPTION_PRINT_GC_SECTIONS:
856218822Sdim	  link_info.print_gc_sections = TRUE;
857218822Sdim	  break;
85833965Sjdp	case OPTION_HELP:
85933965Sjdp	  help ();
86033965Sjdp	  xexit (0);
86133965Sjdp	  break;
86233965Sjdp	case 'L':
863130561Sobrien	  ldfile_add_library_path (optarg, TRUE);
86433965Sjdp	  break;
86533965Sjdp	case 'l':
866130561Sobrien	  lang_add_input_file (optarg, lang_input_file_is_l_enum, NULL);
86733965Sjdp	  break;
86833965Sjdp	case 'M':
86933965Sjdp	  config.map_filename = "-";
87033965Sjdp	  break;
87133965Sjdp	case 'm':
87233965Sjdp	  /* Ignore.  Was handled in a pre-parse.   */
87333965Sjdp	  break;
87433965Sjdp	case OPTION_MAP:
87533965Sjdp	  config.map_filename = optarg;
87633965Sjdp	  break;
87733965Sjdp	case 'N':
878130561Sobrien	  config.text_read_only = FALSE;
879130561Sobrien	  config.magic_demand_paged = FALSE;
880130561Sobrien	  config.dynamic_link = FALSE;
88133965Sjdp	  break;
882130561Sobrien	case OPTION_NO_OMAGIC:
883130561Sobrien	  config.text_read_only = TRUE;
884130561Sobrien	  config.magic_demand_paged = TRUE;
885130561Sobrien	  /* NB/ Does not set dynamic_link to TRUE.
886130561Sobrien	     Use --call-shared or -Bdynamic for this.  */
887130561Sobrien	  break;
88833965Sjdp	case 'n':
889130561Sobrien	  config.magic_demand_paged = FALSE;
890130561Sobrien	  config.dynamic_link = FALSE;
89133965Sjdp	  break;
89289857Sobrien	case OPTION_NO_DEFINE_COMMON:
893130561Sobrien	  command_line.inhibit_common_definition = TRUE;
89489857Sobrien	  break;
89560484Sobrien	case OPTION_NO_DEMANGLE:
896130561Sobrien	  demangling = FALSE;
89760484Sobrien	  break;
89860484Sobrien	case OPTION_NO_GC_SECTIONS:
899218822Sdim	  link_info.gc_sections = FALSE;
90060484Sobrien	  break;
901218822Sdim	case OPTION_NO_PRINT_GC_SECTIONS:
902218822Sdim	  link_info.print_gc_sections = FALSE;
903218822Sdim	  break;
90433965Sjdp	case OPTION_NO_KEEP_MEMORY:
905130561Sobrien	  link_info.keep_memory = FALSE;
90633965Sjdp	  break;
90760484Sobrien	case OPTION_NO_UNDEFINED:
908218822Sdim	  link_info.unresolved_syms_in_objects
909218822Sdim	    = how_to_report_unresolved_symbols;
91060484Sobrien	  break;
91177298Sobrien	case OPTION_ALLOW_SHLIB_UNDEFINED:
912130561Sobrien	  link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
91377298Sobrien	  break;
914130561Sobrien	case OPTION_NO_ALLOW_SHLIB_UNDEFINED:
915218822Sdim	  link_info.unresolved_syms_in_shared_libs
916218822Sdim	    = how_to_report_unresolved_symbols;
917130561Sobrien	  break;
918130561Sobrien	case OPTION_UNRESOLVED_SYMBOLS:
919130561Sobrien	  if (strcmp (optarg, "ignore-all") == 0)
920130561Sobrien	    {
921130561Sobrien	      link_info.unresolved_syms_in_objects = RM_IGNORE;
922130561Sobrien	      link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
923130561Sobrien	    }
924130561Sobrien	  else if (strcmp (optarg, "report-all") == 0)
925130561Sobrien	    {
926218822Sdim	      link_info.unresolved_syms_in_objects
927218822Sdim		= how_to_report_unresolved_symbols;
928218822Sdim	      link_info.unresolved_syms_in_shared_libs
929218822Sdim		= how_to_report_unresolved_symbols;
930130561Sobrien	    }
931130561Sobrien	  else if (strcmp (optarg, "ignore-in-object-files") == 0)
932130561Sobrien	    {
933130561Sobrien	      link_info.unresolved_syms_in_objects = RM_IGNORE;
934218822Sdim	      link_info.unresolved_syms_in_shared_libs
935218822Sdim		= how_to_report_unresolved_symbols;
936130561Sobrien	    }
937130561Sobrien      	  else if (strcmp (optarg, "ignore-in-shared-libs") == 0)
938130561Sobrien	    {
939218822Sdim	      link_info.unresolved_syms_in_objects
940218822Sdim		= how_to_report_unresolved_symbols;
941130561Sobrien	      link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
942130561Sobrien	    }
943130561Sobrien	  else
944130561Sobrien	    einfo (_("%P%F: bad --unresolved-symbols option: %s\n"), optarg);
945130561Sobrien	  break;
946130561Sobrien	case OPTION_WARN_UNRESOLVED_SYMBOLS:
947130561Sobrien	  how_to_report_unresolved_symbols = RM_GENERATE_WARNING;
948130561Sobrien	  if (link_info.unresolved_syms_in_objects == RM_GENERATE_ERROR)
949130561Sobrien	    link_info.unresolved_syms_in_objects = RM_GENERATE_WARNING;
950130561Sobrien	  if (link_info.unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)
951130561Sobrien	    link_info.unresolved_syms_in_shared_libs = RM_GENERATE_WARNING;
952130561Sobrien	  break;
953218822Sdim
954130561Sobrien	case OPTION_ERROR_UNRESOLVED_SYMBOLS:
955130561Sobrien	  how_to_report_unresolved_symbols = RM_GENERATE_ERROR;
956130561Sobrien	  if (link_info.unresolved_syms_in_objects == RM_GENERATE_WARNING)
957130561Sobrien	    link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
958130561Sobrien	  if (link_info.unresolved_syms_in_shared_libs == RM_GENERATE_WARNING)
959130561Sobrien	    link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR;
960218822Sdim	  break;
961104834Sobrien	case OPTION_ALLOW_MULTIPLE_DEFINITION:
962130561Sobrien	  link_info.allow_multiple_definition = TRUE;
963104834Sobrien	  break;
964104834Sobrien	case OPTION_NO_UNDEFINED_VERSION:
965130561Sobrien	  link_info.allow_undefined_version = FALSE;
966104834Sobrien	  break;
967218822Sdim	case OPTION_DEFAULT_SYMVER:
968218822Sdim	  link_info.create_default_symver = TRUE;
969218822Sdim	  break;
970218822Sdim	case OPTION_DEFAULT_IMPORTED_SYMVER:
971218822Sdim	  link_info.default_imported_symver = TRUE;
972218822Sdim	  break;
97338889Sjdp	case OPTION_NO_WARN_MISMATCH:
974130561Sobrien	  command_line.warn_mismatch = FALSE;
97538889Sjdp	  break;
976218822Sdim	case OPTION_NO_WARN_SEARCH_MISMATCH:
977218822Sdim	  command_line.warn_search_mismatch = FALSE;
978218822Sdim	  break;
97933965Sjdp	case OPTION_NOINHIBIT_EXEC:
980130561Sobrien	  force_make_executable = TRUE;
98133965Sjdp	  break;
98289857Sobrien	case OPTION_NOSTDLIB:
983130561Sobrien	  config.only_cmd_line_lib_dirs = TRUE;
98489857Sobrien	  break;
98533965Sjdp	case OPTION_NO_WHOLE_ARCHIVE:
986130561Sobrien	  whole_archive = FALSE;
98733965Sjdp	  break;
98833965Sjdp	case 'O':
98933965Sjdp	  /* FIXME "-O<non-digits> <value>" used to set the address of
99033965Sjdp	     section <non-digits>.  Was this for compatibility with
99133965Sjdp	     something, or can we create a new option to do that
99233965Sjdp	     (with a syntax similar to -defsym)?
99333965Sjdp	     getopt can't handle two args to an option without kludges.  */
99460484Sobrien
99560484Sobrien	  /* Enable optimizations of output files.  */
996130561Sobrien	  link_info.optimize = strtoul (optarg, NULL, 0) ? TRUE : FALSE;
99733965Sjdp	  break;
99833965Sjdp	case 'o':
99977298Sobrien	  lang_add_output (optarg, 0);
100033965Sjdp	  break;
100133965Sjdp	case OPTION_OFORMAT:
1002130561Sobrien	  lang_add_output_format (optarg, NULL, NULL, 0);
100333965Sjdp	  break;
100477298Sobrien	case 'q':
1005130561Sobrien	  link_info.emitrelocations = TRUE;
100677298Sobrien	  break;
100733965Sjdp	case 'i':
100833965Sjdp	case 'r':
100989857Sobrien	  if (optind == last_optind)
101089857Sobrien	    /* This can happen if the user put "-rpath,a" on the command
101189857Sobrien	       line.  (Or something similar.  The comma is important).
101289857Sobrien	       Getopt becomes confused and thinks that this is a -r option
101389857Sobrien	       but it cannot parse the text after the -r so it refuses to
101489857Sobrien	       increment the optind counter.  Detect this case and issue
101589857Sobrien	       an error message here.  We cannot just make this a warning,
101689857Sobrien	       increment optind, and continue because getopt is too confused
101789857Sobrien	       and will seg-fault the next time around.  */
101889857Sobrien	    einfo(_("%P%F: bad -rpath option\n"));
1019104834Sobrien
1020130561Sobrien	  link_info.relocatable = TRUE;
1021130561Sobrien	  config.build_constructors = FALSE;
1022130561Sobrien	  config.magic_demand_paged = FALSE;
1023130561Sobrien	  config.text_read_only = FALSE;
1024130561Sobrien	  config.dynamic_link = FALSE;
102533965Sjdp	  break;
102633965Sjdp	case 'R':
102733965Sjdp	  /* The GNU linker traditionally uses -R to mean to include
102833965Sjdp	     only the symbols from a file.  The Solaris linker uses -R
102933965Sjdp	     to set the path used by the runtime linker to find
103033965Sjdp	     libraries.  This is the GNU linker -rpath argument.  We
103133965Sjdp	     try to support both simultaneously by checking the file
103233965Sjdp	     named.  If it is a directory, rather than a regular file,
103333965Sjdp	     we assume -rpath was meant.  */
103433965Sjdp	  {
103533965Sjdp	    struct stat s;
103633965Sjdp
103733965Sjdp	    if (stat (optarg, &s) >= 0
103833965Sjdp		&& ! S_ISDIR (s.st_mode))
103933965Sjdp	      {
104033965Sjdp		lang_add_input_file (optarg,
104133965Sjdp				     lang_input_file_is_symbols_only_enum,
1042130561Sobrien				     NULL);
104333965Sjdp		break;
104433965Sjdp	      }
104533965Sjdp	  }
104633965Sjdp	  /* Fall through.  */
104733965Sjdp	case OPTION_RPATH:
104833965Sjdp	  if (command_line.rpath == NULL)
104978828Sobrien	    command_line.rpath = xstrdup (optarg);
105033965Sjdp	  else
105133965Sjdp	    {
105260484Sobrien	      size_t rpath_len = strlen (command_line.rpath);
105360484Sobrien	      size_t optarg_len = strlen (optarg);
105433965Sjdp	      char *buf;
105560484Sobrien	      char *cp = command_line.rpath;
105633965Sjdp
105760484Sobrien	      /* First see whether OPTARG is already in the path.  */
105860484Sobrien	      do
105960484Sobrien		{
1060218822Sdim		  if (strncmp (optarg, cp, optarg_len) == 0
1061218822Sdim		      && (cp[optarg_len] == 0
1062218822Sdim			  || cp[optarg_len] == config.rpath_separator))
106360484Sobrien		    /* We found it.  */
106460484Sobrien		    break;
106560484Sobrien
106660484Sobrien		  /* Not yet found.  */
1067218822Sdim		  cp = strchr (cp, config.rpath_separator);
106860484Sobrien		  if (cp != NULL)
106960484Sobrien		    ++cp;
107060484Sobrien		}
107160484Sobrien	      while (cp != NULL);
107260484Sobrien
107360484Sobrien	      if (cp == NULL)
107460484Sobrien		{
107560484Sobrien		  buf = xmalloc (rpath_len + optarg_len + 2);
1076218822Sdim		  sprintf (buf, "%s%c%s", command_line.rpath,
1077218822Sdim			   config.rpath_separator, optarg);
107860484Sobrien		  free (command_line.rpath);
107960484Sobrien		  command_line.rpath = buf;
108060484Sobrien		}
108133965Sjdp	    }
108233965Sjdp	  break;
108333965Sjdp	case OPTION_RPATH_LINK:
108433965Sjdp	  if (command_line.rpath_link == NULL)
108578828Sobrien	    command_line.rpath_link = xstrdup (optarg);
108633965Sjdp	  else
108733965Sjdp	    {
108833965Sjdp	      char *buf;
108933965Sjdp
109033965Sjdp	      buf = xmalloc (strlen (command_line.rpath_link)
109133965Sjdp			     + strlen (optarg)
109233965Sjdp			     + 2);
1093218822Sdim	      sprintf (buf, "%s%c%s", command_line.rpath_link,
1094218822Sdim		       config.rpath_separator, optarg);
109533965Sjdp	      free (command_line.rpath_link);
109633965Sjdp	      command_line.rpath_link = buf;
109733965Sjdp	    }
109833965Sjdp	  break;
109933965Sjdp	case OPTION_RELAX:
1100130561Sobrien	  command_line.relax = TRUE;
110133965Sjdp	  break;
110233965Sjdp	case OPTION_RETAIN_SYMBOLS_FILE:
110333965Sjdp	  add_keepsyms_file (optarg);
110433965Sjdp	  break;
110533965Sjdp	case 'S':
110633965Sjdp	  link_info.strip = strip_debugger;
110733965Sjdp	  break;
110833965Sjdp	case 's':
110933965Sjdp	  link_info.strip = strip_all;
111033965Sjdp	  break;
1111130561Sobrien	case OPTION_STRIP_DISCARDED:
1112130561Sobrien	  link_info.strip_discarded = TRUE;
1113130561Sobrien	  break;
1114130561Sobrien	case OPTION_NO_STRIP_DISCARDED:
1115130561Sobrien	  link_info.strip_discarded = FALSE;
1116130561Sobrien	  break;
111733965Sjdp	case OPTION_SHARED:
111860484Sobrien	  if (config.has_shared)
1119130561Sobrien	    {
1120130561Sobrien	      link_info.shared = TRUE;
1121130561Sobrien	      /* When creating a shared library, the default
1122130561Sobrien		 behaviour is to ignore any unresolved references.  */
1123130561Sobrien	      if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
1124130561Sobrien		link_info.unresolved_syms_in_objects = RM_IGNORE;
1125130561Sobrien	      if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
1126130561Sobrien		link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
1127130561Sobrien	    }
112860484Sobrien	  else
112960484Sobrien	    einfo (_("%P%F: -shared not supported\n"));
113033965Sjdp	  break;
1131130561Sobrien	case OPTION_PIE:
1132130561Sobrien	  if (config.has_shared)
1133130561Sobrien	    {
1134130561Sobrien	      link_info.shared = TRUE;
1135130561Sobrien	      link_info.pie = TRUE;
1136130561Sobrien	    }
1137130561Sobrien	  else
1138130561Sobrien	    einfo (_("%P%F: -pie not supported\n"));
1139130561Sobrien	  break;
114033965Sjdp	case 'h':		/* Used on Solaris.  */
114133965Sjdp	case OPTION_SONAME:
114233965Sjdp	  command_line.soname = optarg;
114333965Sjdp	  break;
114433965Sjdp	case OPTION_SORT_COMMON:
1145130561Sobrien	  config.sort_common = TRUE;
114633965Sjdp	  break;
1147218822Sdim	case OPTION_SORT_SECTION:
1148218822Sdim	  if (strcmp (optarg, N_("name")) == 0)
1149218822Sdim	    sort_section = by_name;
1150218822Sdim	  else if (strcmp (optarg, N_("alignment")) == 0)
1151218822Sdim	    sort_section = by_alignment;
1152218822Sdim	  else
1153218822Sdim	    einfo (_("%P%F: invalid section sorting option: %s\n"),
1154218822Sdim		   optarg);
1155218822Sdim	  break;
115633965Sjdp	case OPTION_STATS:
1157130561Sobrien	  config.stats = TRUE;
115833965Sjdp	  break;
115933965Sjdp	case OPTION_SYMBOLIC:
1160218822Sdim	  command_line.symbolic = symbolic;
116133965Sjdp	  break;
1162218822Sdim	case OPTION_SYMBOLIC_FUNCTIONS:
1163218822Sdim	  command_line.symbolic = symbolic_functions;
1164218822Sdim	  break;
116533965Sjdp	case 't':
1166130561Sobrien	  trace_files = TRUE;
116733965Sjdp	  break;
116833965Sjdp	case 'T':
116933965Sjdp	  ldfile_open_command_file (optarg);
117033965Sjdp	  parser_input = input_script;
117133965Sjdp	  yyparse ();
117233965Sjdp	  break;
1173218822Sdim	case OPTION_DEFAULT_SCRIPT:
1174218822Sdim	  command_line.default_script = optarg;
1175218822Sdim	  break;
117677298Sobrien	case OPTION_SECTION_START:
117777298Sobrien	  {
117877298Sobrien	    char *optarg2;
117977298Sobrien	    char *sec_name;
118077298Sobrien	    int len;
118177298Sobrien
118277298Sobrien	    /* Check for <something>=<somthing>...  */
118377298Sobrien	    optarg2 = strchr (optarg, '=');
118477298Sobrien	    if (optarg2 == NULL)
1185218822Sdim	      einfo (_("%P%F: invalid argument to option"
1186218822Sdim		       " \"--section-start\"\n"));
118777298Sobrien
118877298Sobrien	    optarg2++;
118977298Sobrien
119077298Sobrien	    /* So far so good.  Are all the args present?  */
119177298Sobrien	    if ((*optarg == '\0') || (*optarg2 == '\0'))
1192218822Sdim	      einfo (_("%P%F: missing argument(s) to option"
1193218822Sdim		       " \"--section-start\"\n"));
119477298Sobrien
119577298Sobrien	    /* We must copy the section name as set_section_start
119677298Sobrien	       doesn't do it for us.  */
119777298Sobrien	    len = optarg2 - optarg;
119877298Sobrien	    sec_name = xmalloc (len);
119977298Sobrien	    memcpy (sec_name, optarg, len - 1);
120077298Sobrien	    sec_name[len - 1] = 0;
120177298Sobrien
120277298Sobrien	    /* Then set it...  */
120377298Sobrien	    set_section_start (sec_name, optarg2);
120477298Sobrien	  }
120577298Sobrien	  break;
120677298Sobrien	case OPTION_TARGET_HELP:
120777298Sobrien	  /* Mention any target specific options.  */
1208104834Sobrien	  ldemul_list_emulation_options (stdout);
1209104834Sobrien	  exit (0);
121033965Sjdp	case OPTION_TBSS:
1211218822Sdim	  set_segment_start (".bss", optarg);
121233965Sjdp	  break;
121333965Sjdp	case OPTION_TDATA:
1214218822Sdim	  set_segment_start (".data", optarg);
121533965Sjdp	  break;
121633965Sjdp	case OPTION_TTEXT:
1217218822Sdim	  set_segment_start (".text", optarg);
121833965Sjdp	  break;
121933965Sjdp	case OPTION_TRADITIONAL_FORMAT:
1220130561Sobrien	  link_info.traditional_format = TRUE;
122133965Sjdp	  break;
122238889Sjdp	case OPTION_TASK_LINK:
1223130561Sobrien	  link_info.task_link = TRUE;
122438889Sjdp	  /* Fall through - do an implied -r option.  */
122533965Sjdp	case OPTION_UR:
1226130561Sobrien	  link_info.relocatable = TRUE;
1227130561Sobrien	  config.build_constructors = TRUE;
1228130561Sobrien	  config.magic_demand_paged = FALSE;
1229130561Sobrien	  config.text_read_only = FALSE;
1230130561Sobrien	  config.dynamic_link = FALSE;
123133965Sjdp	  break;
123233965Sjdp	case 'u':
123333965Sjdp	  ldlang_add_undef (optarg);
123433965Sjdp	  break;
123577298Sobrien	case OPTION_UNIQUE:
123677298Sobrien	  if (optarg != NULL)
123777298Sobrien	    lang_add_unique (optarg);
123877298Sobrien	  else
1239130561Sobrien	    config.unique_orphan_sections = TRUE;
124077298Sobrien	  break;
124133965Sjdp	case OPTION_VERBOSE:
124233965Sjdp	  ldversion (1);
1243130561Sobrien	  version_printed = TRUE;
1244130561Sobrien	  trace_file_tries = TRUE;
1245130561Sobrien	  overflow_cutoff_limit = -2;
124633965Sjdp	  break;
124733965Sjdp	case 'v':
124833965Sjdp	  ldversion (0);
1249130561Sobrien	  version_printed = TRUE;
125033965Sjdp	  break;
125133965Sjdp	case 'V':
125233965Sjdp	  ldversion (1);
1253130561Sobrien	  version_printed = TRUE;
125433965Sjdp	  break;
125533965Sjdp	case OPTION_VERSION:
125689857Sobrien	  ldversion (2);
125733965Sjdp	  xexit (0);
125833965Sjdp	  break;
125933965Sjdp	case OPTION_VERSION_SCRIPT:
126033965Sjdp	  /* This option indicates a small script that only specifies
1261130561Sobrien	     version information.  Read it, but don't assume that
1262130561Sobrien	     we've seen a linker script.  */
126333965Sjdp	  {
1264104834Sobrien	    FILE *hold_script_handle;
126533965Sjdp
126689857Sobrien	    hold_script_handle = saved_script_handle;
126733965Sjdp	    ldfile_open_command_file (optarg);
126889857Sobrien	    saved_script_handle = hold_script_handle;
126933965Sjdp	    parser_input = input_version_script;
127033965Sjdp	    yyparse ();
127133965Sjdp	  }
127233965Sjdp	  break;
127360484Sobrien	case OPTION_VERSION_EXPORTS_SECTION:
127460484Sobrien	  /* This option records a version symbol to be applied to the
127560484Sobrien	     symbols listed for export to be found in the object files
127660484Sobrien	     .exports sections.  */
127760484Sobrien	  command_line.version_exports_section = optarg;
127860484Sobrien	  break;
1279218822Sdim	case OPTION_DYNAMIC_LIST_DATA:
1280218822Sdim	  command_line.dynamic_list = dynamic_list_data;
1281218822Sdim	  if (command_line.symbolic == symbolic)
1282218822Sdim	    command_line.symbolic = symbolic_unset;
1283218822Sdim	  break;
1284218822Sdim	case OPTION_DYNAMIC_LIST_CPP_TYPEINFO:
1285218822Sdim	  lang_append_dynamic_list_cpp_typeinfo ();
1286218822Sdim	  if (command_line.dynamic_list != dynamic_list_data)
1287218822Sdim	    command_line.dynamic_list = dynamic_list;
1288218822Sdim	  if (command_line.symbolic == symbolic)
1289218822Sdim	    command_line.symbolic = symbolic_unset;
1290218822Sdim	  break;
1291218822Sdim	case OPTION_DYNAMIC_LIST_CPP_NEW:
1292218822Sdim	  lang_append_dynamic_list_cpp_new ();
1293218822Sdim	  if (command_line.dynamic_list != dynamic_list_data)
1294218822Sdim	    command_line.dynamic_list = dynamic_list;
1295218822Sdim	  if (command_line.symbolic == symbolic)
1296218822Sdim	    command_line.symbolic = symbolic_unset;
1297218822Sdim	  break;
1298218822Sdim	case OPTION_DYNAMIC_LIST:
1299218822Sdim	  /* This option indicates a small script that only specifies
1300218822Sdim	     a dynamic list.  Read it, but don't assume that we've
1301218822Sdim	     seen a linker script.  */
1302218822Sdim	  {
1303218822Sdim	    FILE *hold_script_handle;
1304218822Sdim
1305218822Sdim	    hold_script_handle = saved_script_handle;
1306218822Sdim	    ldfile_open_command_file (optarg);
1307218822Sdim	    saved_script_handle = hold_script_handle;
1308218822Sdim	    parser_input = input_dynamic_list;
1309218822Sdim	    yyparse ();
1310218822Sdim	  }
1311218822Sdim	  if (command_line.dynamic_list != dynamic_list_data)
1312218822Sdim	    command_line.dynamic_list = dynamic_list;
1313218822Sdim	  if (command_line.symbolic == symbolic)
1314218822Sdim	    command_line.symbolic = symbolic_unset;
1315218822Sdim	  break;
131633965Sjdp	case OPTION_WARN_COMMON:
1317130561Sobrien	  config.warn_common = TRUE;
131833965Sjdp	  break;
131933965Sjdp	case OPTION_WARN_CONSTRUCTORS:
1320130561Sobrien	  config.warn_constructors = TRUE;
132133965Sjdp	  break;
132289857Sobrien	case OPTION_WARN_FATAL:
1323130561Sobrien	  config.fatal_warnings = TRUE;
132489857Sobrien	  break;
1325306136Semaste	case OPTION_NO_WARN_FATAL:
1326306136Semaste	  no_fatal_warnings = TRUE;
1327306136Semaste	  break;
132833965Sjdp	case OPTION_WARN_MULTIPLE_GP:
1329130561Sobrien	  config.warn_multiple_gp = TRUE;
133033965Sjdp	  break;
133133965Sjdp	case OPTION_WARN_ONCE:
1332130561Sobrien	  config.warn_once = TRUE;
133333965Sjdp	  break;
133433965Sjdp	case OPTION_WARN_SECTION_ALIGN:
1335130561Sobrien	  config.warn_section_align = TRUE;
133633965Sjdp	  break;
1337218822Sdim	case OPTION_WARN_SHARED_TEXTREL:
1338218822Sdim	  link_info.warn_shared_textrel = TRUE;
1339218822Sdim	  break;
134033965Sjdp	case OPTION_WHOLE_ARCHIVE:
1341130561Sobrien	  whole_archive = TRUE;
134233965Sjdp	  break;
1343218822Sdim	case OPTION_ADD_NEEDED:
1344218822Sdim	  add_needed = TRUE;
1345218822Sdim	  break;
1346218822Sdim	case OPTION_NO_ADD_NEEDED:
1347218822Sdim	  add_needed = FALSE;
1348218822Sdim	  break;
1349130561Sobrien	case OPTION_AS_NEEDED:
1350209867Snwhitehorn/* XXX: --as-needed is broken on powerpc64 */
1351209867Snwhitehorn#ifndef __powerpc64__
1352130561Sobrien	  as_needed = TRUE;
1353130561Sobrien	  break;
1354209867Snwhitehorn#endif
1355130561Sobrien	case OPTION_NO_AS_NEEDED:
1356130561Sobrien	  as_needed = FALSE;
1357130561Sobrien	  break;
135833965Sjdp	case OPTION_WRAP:
135933965Sjdp	  add_wrap (optarg);
136033965Sjdp	  break;
136189857Sobrien	case OPTION_DISCARD_NONE:
136289857Sobrien	  link_info.discard = discard_none;
136389857Sobrien	  break;
136433965Sjdp	case 'X':
136533965Sjdp	  link_info.discard = discard_l;
136633965Sjdp	  break;
136733965Sjdp	case 'x':
136833965Sjdp	  link_info.discard = discard_all;
136933965Sjdp	  break;
137033965Sjdp	case 'Y':
1371218822Sdim	  if (CONST_STRNEQ (optarg, "P,"))
137233965Sjdp	    optarg += 2;
1373130561Sobrien	  if (default_dirlist != NULL)
1374130561Sobrien	    free (default_dirlist);
137533965Sjdp	  default_dirlist = xstrdup (optarg);
137633965Sjdp	  break;
137733965Sjdp	case 'y':
137833965Sjdp	  add_ysym (optarg);
137933965Sjdp	  break;
138089857Sobrien	case OPTION_SPARE_DYNAMIC_TAGS:
138189857Sobrien	  link_info.spare_dynamic_tags = strtoul (optarg, NULL, 0);
138289857Sobrien	  break;
138377298Sobrien	case OPTION_SPLIT_BY_RELOC:
138477298Sobrien	  if (optarg != NULL)
138577298Sobrien	    config.split_by_reloc = strtoul (optarg, NULL, 0);
138677298Sobrien	  else
138777298Sobrien	    config.split_by_reloc = 32768;
138833965Sjdp	  break;
138933965Sjdp	case OPTION_SPLIT_BY_FILE:
139077298Sobrien	  if (optarg != NULL)
139177298Sobrien	    config.split_by_file = bfd_scan_vma (optarg, NULL, 0);
139277298Sobrien	  else
139377298Sobrien	    config.split_by_file = 1;
139477298Sobrien	  break;
139560484Sobrien	case OPTION_CHECK_SECTIONS:
1396130561Sobrien	  command_line.check_section_addresses = TRUE;
139760484Sobrien	  break;
139860484Sobrien	case OPTION_NO_CHECK_SECTIONS:
1399130561Sobrien	  command_line.check_section_addresses = FALSE;
140060484Sobrien	  break;
1401130561Sobrien	case OPTION_ACCEPT_UNKNOWN_INPUT_ARCH:
1402130561Sobrien	  command_line.accept_unknown_input_arch = TRUE;
1403130561Sobrien	  break;
1404130561Sobrien	case OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH:
1405130561Sobrien	  command_line.accept_unknown_input_arch = FALSE;
1406130561Sobrien	  break;
140733965Sjdp	case '(':
140833965Sjdp	  if (ingroup)
140989857Sobrien	    einfo (_("%P%F: may not nest groups (--help for usage)\n"));
141089857Sobrien
141133965Sjdp	  lang_enter_group ();
141233965Sjdp	  ingroup = 1;
141333965Sjdp	  break;
141433965Sjdp	case ')':
141533965Sjdp	  if (! ingroup)
141689857Sobrien	    einfo (_("%P%F: group ended before it began (--help for usage)\n"));
141789857Sobrien
141833965Sjdp	  lang_leave_group ();
141933965Sjdp	  ingroup = 0;
142033965Sjdp	  break;
142133965Sjdp
142260484Sobrien	case OPTION_INIT:
142360484Sobrien	  link_info.init_function = optarg;
142460484Sobrien	  break;
142577298Sobrien
142660484Sobrien	case OPTION_FINI:
142760484Sobrien	  link_info.fini_function = optarg;
142860484Sobrien	  break;
1429218822Sdim
1430218822Sdim	case OPTION_REDUCE_MEMORY_OVERHEADS:
1431218822Sdim	  link_info.reduce_memory_overheads = TRUE;
1432218822Sdim	  if (config.hash_table_size == 0)
1433218822Sdim	    config.hash_table_size = 1021;
1434218822Sdim	  break;
1435218822Sdim
1436218822Sdim        case OPTION_HASH_SIZE:
1437218822Sdim	  {
1438218822Sdim	    bfd_size_type new_size;
1439218822Sdim
1440218822Sdim            new_size = strtoul (optarg, NULL, 0);
1441218822Sdim            if (new_size)
1442218822Sdim              config.hash_table_size = new_size;
1443218822Sdim            else
1444218822Sdim              einfo (_("%P%X: --hash-size needs a numeric argument\n"));
1445218822Sdim          }
1446218822Sdim          break;
144733965Sjdp	}
144833965Sjdp    }
1449306136Semaste  if (no_fatal_warnings)
1450306136Semaste    config.fatal_warnings = FALSE;
145133965Sjdp
145233965Sjdp  if (ingroup)
145333965Sjdp    lang_leave_group ();
145433965Sjdp
145533965Sjdp  if (default_dirlist != NULL)
1456130561Sobrien    {
1457130561Sobrien      set_default_dirlist (default_dirlist);
1458130561Sobrien      free (default_dirlist);
1459130561Sobrien    }
146033965Sjdp
1461130561Sobrien  if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
1462130561Sobrien    /* FIXME: Should we allow emulations a chance to set this ?  */
1463130561Sobrien    link_info.unresolved_syms_in_objects = how_to_report_unresolved_symbols;
1464218822Sdim
1465130561Sobrien  if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
1466130561Sobrien    /* FIXME: Should we allow emulations a chance to set this ?  */
1467130561Sobrien    link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
146833965Sjdp}
146933965Sjdp
147033965Sjdp/* Add the (colon-separated) elements of DIRLIST_PTR to the
147133965Sjdp   library search path.  */
147233965Sjdp
147333965Sjdpstatic void
1474130561Sobrienset_default_dirlist (char *dirlist_ptr)
147533965Sjdp{
147633965Sjdp  char *p;
147733965Sjdp
147833965Sjdp  while (1)
147933965Sjdp    {
148038889Sjdp      p = strchr (dirlist_ptr, PATH_SEPARATOR);
148133965Sjdp      if (p != NULL)
148233965Sjdp	*p = '\0';
148333965Sjdp      if (*dirlist_ptr != '\0')
1484130561Sobrien	ldfile_add_library_path (dirlist_ptr, TRUE);
148533965Sjdp      if (p == NULL)
148633965Sjdp	break;
148733965Sjdp      dirlist_ptr = p + 1;
148833965Sjdp    }
148933965Sjdp}
149033965Sjdp
149133965Sjdpstatic void
1492130561Sobrienset_section_start (char *sect, char *valstr)
149333965Sjdp{
149460484Sobrien  const char *end;
149560484Sobrien  bfd_vma val = bfd_scan_vma (valstr, &end, 16);
149633965Sjdp  if (*end)
149760484Sobrien    einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
1498218822Sdim  lang_section_start (sect, exp_intop (val), NULL);
149933965Sjdp}
1500218822Sdim
1501218822Sdimstatic void
1502218822Sdimset_segment_start (const char *section, char *valstr)
1503218822Sdim{
1504218822Sdim  const char *name;
1505218822Sdim  const char *end;
1506218822Sdim  segment_type *seg;
1507218822Sdim
1508218822Sdim  bfd_vma val = bfd_scan_vma (valstr, &end, 16);
1509218822Sdim  if (*end)
1510218822Sdim    einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
1511218822Sdim  /* If we already have an entry for this segment, update the existing
1512218822Sdim     value.  */
1513218822Sdim  name = section + 1;
1514218822Sdim  for (seg = segments; seg; seg = seg->next)
1515218822Sdim    if (strcmp (seg->name, name) == 0)
1516218822Sdim      {
1517218822Sdim	seg->value = val;
1518218822Sdim	return;
1519218822Sdim      }
1520218822Sdim  /* There was no existing value so we must create a new segment
1521218822Sdim     entry.  */
1522218822Sdim  seg = stat_alloc (sizeof (*seg));
1523218822Sdim  seg->name = name;
1524218822Sdim  seg->value = val;
1525218822Sdim  seg->used = FALSE;
1526218822Sdim  /* Add it to the linked list of segments.  */
1527218822Sdim  seg->next = segments;
1528218822Sdim  segments = seg;
1529218822Sdim  /* Historically, -Ttext and friends set the base address of a
1530218822Sdim     particular section.  For backwards compatibility, we still do
1531218822Sdim     that.  If a SEGMENT_START directive is seen, the section address
1532218822Sdim     assignment will be disabled.  */
1533218822Sdim  lang_section_start (section, exp_intop (val), seg);
1534218822Sdim}
1535218822Sdim
153633965Sjdp
153733965Sjdp/* Print help messages for the options.  */
153833965Sjdp
153933965Sjdpstatic void
1540130561Sobrienhelp (void)
154133965Sjdp{
154277298Sobrien  unsigned i;
154333965Sjdp  const char **targets, **pp;
1544218822Sdim  int len;
154533965Sjdp
154660484Sobrien  printf (_("Usage: %s [options] file...\n"), program_name);
154733965Sjdp
154860484Sobrien  printf (_("Options:\n"));
154933965Sjdp  for (i = 0; i < OPTION_COUNT; i++)
155033965Sjdp    {
155133965Sjdp      if (ld_options[i].doc != NULL)
155233965Sjdp	{
1553130561Sobrien	  bfd_boolean comma;
155477298Sobrien	  unsigned j;
155533965Sjdp
155633965Sjdp	  printf ("  ");
155733965Sjdp
1558130561Sobrien	  comma = FALSE;
155933965Sjdp	  len = 2;
156033965Sjdp
156133965Sjdp	  j = i;
156233965Sjdp	  do
156333965Sjdp	    {
156433965Sjdp	      if (ld_options[j].shortopt != '\0'
156533965Sjdp		  && ld_options[j].control != NO_HELP)
156633965Sjdp		{
156733965Sjdp		  printf ("%s-%c", comma ? ", " : "", ld_options[j].shortopt);
156833965Sjdp		  len += (comma ? 2 : 0) + 2;
156933965Sjdp		  if (ld_options[j].arg != NULL)
157033965Sjdp		    {
157133965Sjdp		      if (ld_options[j].opt.has_arg != optional_argument)
157233965Sjdp			{
157333965Sjdp			  printf (" ");
157433965Sjdp			  ++len;
157533965Sjdp			}
157660484Sobrien		      printf ("%s", _(ld_options[j].arg));
157760484Sobrien		      len += strlen (_(ld_options[j].arg));
157833965Sjdp		    }
1579130561Sobrien		  comma = TRUE;
158033965Sjdp		}
158133965Sjdp	      ++j;
158233965Sjdp	    }
158333965Sjdp	  while (j < OPTION_COUNT && ld_options[j].doc == NULL);
158433965Sjdp
158533965Sjdp	  j = i;
158633965Sjdp	  do
158733965Sjdp	    {
158833965Sjdp	      if (ld_options[j].opt.name != NULL
158933965Sjdp		  && ld_options[j].control != NO_HELP)
159033965Sjdp		{
159177298Sobrien		  int two_dashes =
159277298Sobrien		    (ld_options[j].control == TWO_DASHES
159377298Sobrien		     || ld_options[j].control == EXACTLY_TWO_DASHES);
1594104834Sobrien
159533965Sjdp		  printf ("%s-%s%s",
159633965Sjdp			  comma ? ", " : "",
159777298Sobrien			  two_dashes ? "-" : "",
159833965Sjdp			  ld_options[j].opt.name);
159933965Sjdp		  len += ((comma ? 2 : 0)
160033965Sjdp			  + 1
160177298Sobrien			  + (two_dashes ? 1 : 0)
160233965Sjdp			  + strlen (ld_options[j].opt.name));
160333965Sjdp		  if (ld_options[j].arg != NULL)
160433965Sjdp		    {
160560484Sobrien		      printf (" %s", _(ld_options[j].arg));
160660484Sobrien		      len += 1 + strlen (_(ld_options[j].arg));
160733965Sjdp		    }
1608130561Sobrien		  comma = TRUE;
160933965Sjdp		}
161033965Sjdp	      ++j;
161133965Sjdp	    }
161233965Sjdp	  while (j < OPTION_COUNT && ld_options[j].doc == NULL);
161333965Sjdp
161433965Sjdp	  if (len >= 30)
161533965Sjdp	    {
161633965Sjdp	      printf ("\n");
161733965Sjdp	      len = 0;
161833965Sjdp	    }
161933965Sjdp
162033965Sjdp	  for (; len < 30; len++)
162133965Sjdp	    putchar (' ');
162233965Sjdp
162360484Sobrien	  printf ("%s\n", _(ld_options[i].doc));
162433965Sjdp	}
162533965Sjdp    }
1626218822Sdim  printf (_("  @FILE"));
1627218822Sdim  for (len = strlen ("  @FILE"); len < 30; len++)
1628218822Sdim    putchar (' ');
1629218822Sdim  printf (_("Read options from FILE\n"));
163033965Sjdp
163160484Sobrien  /* Note: Various tools (such as libtool) depend upon the
163260484Sobrien     format of the listings below - do not change them.  */
163360484Sobrien  /* xgettext:c-format */
163460484Sobrien  printf (_("%s: supported targets:"), program_name);
163533965Sjdp  targets = bfd_target_list ();
163633965Sjdp  for (pp = targets; *pp != NULL; pp++)
163733965Sjdp    printf (" %s", *pp);
163833965Sjdp  free (targets);
163933965Sjdp  printf ("\n");
164033965Sjdp
164160484Sobrien  /* xgettext:c-format */
164260484Sobrien  printf (_("%s: supported emulations: "), program_name);
164333965Sjdp  ldemul_list_emulations (stdout);
164433965Sjdp  printf ("\n");
164560484Sobrien
164660484Sobrien  /* xgettext:c-format */
164760484Sobrien  printf (_("%s: emulation specific options:\n"), program_name);
164860484Sobrien  ldemul_list_emulation_options (stdout);
164960484Sobrien  printf ("\n");
165060484Sobrien
1651218822Sdim  if (REPORT_BUGS_TO[0])
1652218822Sdim    printf (_("Report bugs to %s\n"), REPORT_BUGS_TO);
165333965Sjdp}
1654