lexsup.c revision 38889
1139825Simp/* Parse options for the GNU linker.
21541Srgrimes   Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998
31549Srgrimes   Free Software Foundation, Inc.
41549Srgrimes
59507SdgThis file is part of GLD, the Gnu Linker.
69507Sdg
71541SrgrimesGLD is free software; you can redistribute it and/or modify
81541Srgrimesit under the terms of the GNU General Public License as published by
91541Srgrimesthe Free Software Foundation; either version 2, or (at your option)
101541Srgrimesany later version.
111541Srgrimes
121541SrgrimesGLD is distributed in the hope that it will be useful,
131541Srgrimesbut WITHOUT ANY WARRANTY; without even the implied warranty of
141541SrgrimesMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
151541SrgrimesGNU General Public License for more details.
161541Srgrimes
171541SrgrimesYou should have received a copy of the GNU General Public License
181541Srgrimesalong with GLD; see the file COPYING.  If not, write to the Free
191541SrgrimesSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
201541Srgrimes02111-1307, USA.  */
2158705Scharnier
221541Srgrimes#include "bfd.h"
231541Srgrimes#include "sysdep.h"
241541Srgrimes#include "libiberty.h"
251541Srgrimes#include <stdio.h>
261541Srgrimes#include <string.h>
271541Srgrimes#include <ctype.h>
281541Srgrimes#include "getopt.h"
291541Srgrimes#include "bfdlink.h"
301541Srgrimes#include "ld.h"
311541Srgrimes#include "ldmain.h"
321541Srgrimes#include "ldmisc.h"
331541Srgrimes#include "ldexp.h"
341541Srgrimes#include "ldlang.h"
351541Srgrimes#include "ldgram.h"
361541Srgrimes#include "ldlex.h"
371541Srgrimes#include "ldfile.h"
381541Srgrimes#include "ldver.h"
391541Srgrimes#include "ldemul.h"
401549Srgrimes
411541Srgrimes#ifndef PATH_SEPARATOR
421541Srgrimes#if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN32__))
431541Srgrimes#define PATH_SEPARATOR ';'
441541Srgrimes#else
451541Srgrimes#define PATH_SEPARATOR ':'
461541Srgrimes#endif
471549Srgrimes#endif
481549Srgrimes
499507Sdg/* Somewhere above, sys/stat.h got included . . . . */
507695Sdg#if !defined(S_ISDIR) && defined(S_IFDIR)
511549Srgrimes#define	S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
521549Srgrimes#endif
53116226Sobrien
54116226Sobrien/* Omit args to avoid the possibility of clashing with a system header
55116226Sobrien   that might disagree about consts.  */
561541Srgrimesunsigned long strtoul ();
571541Srgrimes
581541Srgrimesstatic void set_default_dirlist PARAMS ((char *dirlist_ptr));
591541Srgrimesstatic void set_section_start PARAMS ((char *sect, char *valstr));
601541Srgrimesstatic void help PARAMS ((void));
6160041Sphk
629507Sdg/* Non-zero if we are processing a --defsym from the command line.  */
6312662Sdgint parsing_defsym = 0;
64140767Sphk
6551340Sdillon/* Codes used for the long options with no short synonyms.  150 isn't
66127926Salc   special; it's just an arbitrary non-ASCII char value.  */
671541Srgrimes
68148875Sssouhlal#define OPTION_ASSERT			150
69148875Sssouhlal#define OPTION_CALL_SHARED		(OPTION_ASSERT + 1)
701541Srgrimes#define OPTION_CREF			(OPTION_CALL_SHARED + 1)
7112662Sdg#define OPTION_DEFSYM			(OPTION_CREF + 1)
721541Srgrimes#define OPTION_DYNAMIC_LINKER		(OPTION_DEFSYM + 1)
739507Sdg#define OPTION_EB			(OPTION_DYNAMIC_LINKER + 1)
7431853Sdyson#define OPTION_EL			(OPTION_EB + 1)
751541Srgrimes#define OPTION_EMBEDDED_RELOCS		(OPTION_EL + 1)
7612662Sdg#define OPTION_EXPORT_DYNAMIC		(OPTION_EMBEDDED_RELOCS + 1)
771541Srgrimes#define OPTION_HELP			(OPTION_EXPORT_DYNAMIC + 1)
78163359Salc#define OPTION_IGNORE			(OPTION_HELP + 1)
79163359Salc#define OPTION_MAP			(OPTION_IGNORE + 1)
8092727Salfred#define OPTION_NO_KEEP_MEMORY		(OPTION_MAP + 1)
8192727Salfred#define OPTION_NO_WARN_MISMATCH		(OPTION_NO_KEEP_MEMORY + 1)
8292727Salfred#define OPTION_NOINHIBIT_EXEC		(OPTION_NO_WARN_MISMATCH + 1)
8392727Salfred#define OPTION_NON_SHARED		(OPTION_NOINHIBIT_EXEC + 1)
8492727Salfred#define OPTION_NO_WHOLE_ARCHIVE		(OPTION_NON_SHARED + 1)
8592727Salfred#define OPTION_OFORMAT			(OPTION_NO_WHOLE_ARCHIVE + 1)
86194766Skib#define OPTION_RELAX			(OPTION_OFORMAT + 1)
87194766Skib#define OPTION_RETAIN_SYMBOLS_FILE	(OPTION_RELAX + 1)
8811943Sbde#define OPTION_RPATH			(OPTION_RETAIN_SYMBOLS_FILE + 1)
891541Srgrimes#define OPTION_RPATH_LINK		(OPTION_RPATH + 1)
90118466Sphk#define OPTION_SHARED			(OPTION_RPATH_LINK + 1)
91118466Sphk#define OPTION_SONAME			(OPTION_SHARED + 1)
92118466Sphk#define OPTION_SORT_COMMON		(OPTION_SONAME + 1)
93118466Sphk#define OPTION_STATS			(OPTION_SORT_COMMON + 1)
94118466Sphk#define OPTION_SYMBOLIC			(OPTION_STATS + 1)
951541Srgrimes#define OPTION_TASK_LINK		(OPTION_SYMBOLIC + 1)
961541Srgrimes#define OPTION_TBSS			(OPTION_TASK_LINK + 1)
9779127Sjhb#define OPTION_TDATA			(OPTION_TBSS + 1)
9810556Sdyson#define OPTION_TTEXT			(OPTION_TDATA + 1)
99140767Sphk#define OPTION_TRADITIONAL_FORMAT	(OPTION_TTEXT + 1)
100140767Sphk#define OPTION_UR			(OPTION_TRADITIONAL_FORMAT + 1)
101155177Syar#define OPTION_VERBOSE			(OPTION_UR + 1)
102140767Sphk#define OPTION_VERSION			(OPTION_VERBOSE + 1)
103140767Sphk#define OPTION_VERSION_SCRIPT		(OPTION_VERSION + 1)
104140767Sphk#define OPTION_WARN_COMMON		(OPTION_VERSION_SCRIPT + 1)
105140767Sphk#define OPTION_WARN_CONSTRUCTORS	(OPTION_WARN_COMMON + 1)
106140767Sphk#define OPTION_WARN_MULTIPLE_GP		(OPTION_WARN_CONSTRUCTORS + 1)
107140767Sphk#define OPTION_WARN_ONCE		(OPTION_WARN_MULTIPLE_GP + 1)
108140767Sphk#define OPTION_WARN_SECTION_ALIGN	(OPTION_WARN_ONCE + 1)
109140767Sphk#define OPTION_SPLIT_BY_RELOC		(OPTION_WARN_SECTION_ALIGN + 1)
110140767Sphk#define OPTION_SPLIT_BY_FILE 	    	(OPTION_SPLIT_BY_RELOC + 1)
111140767Sphk#define OPTION_WHOLE_ARCHIVE		(OPTION_SPLIT_BY_FILE + 1)
112140767Sphk#define OPTION_WRAP			(OPTION_WHOLE_ARCHIVE + 1)
113140767Sphk#define OPTION_FORCE_EXE_SUFFIX		(OPTION_WRAP + 1)
114140767Sphk
115140767Sphk/* The long options.  This structure is used for both the option
116175294Sattilio   parsing and the help text.  */
117140767Sphk
118140767Sphkstruct ld_option
119175202Sattilio{
120140767Sphk  /* The long option information.  */
121140767Sphk  struct option opt;
122140767Sphk  /* The short option with the same meaning ('\0' if none).  */
123140767Sphk  char shortopt;
124140767Sphk  /* The name of the argument (NULL if none).  */
125140767Sphk  const char *arg;
126182371Sattilio  /* The documentation string.  If this is NULL, this is a synonym for
127140767Sphk     the previous option.  */
128140767Sphk  const char *doc;
129140767Sphk  enum
130140767Sphk    {
131140767Sphk      /* Use one dash before long option name.  */
132194766Skib      ONE_DASH,
133140767Sphk      /* Use two dashes before long option name.  */
134140767Sphk      TWO_DASHES,
135140767Sphk      /* Don't mention this option in --help output.  */
136140767Sphk      NO_HELP
137140767Sphk    } control;
138140767Sphk};
139140767Sphk
140140767Sphkstatic const struct ld_option ld_options[] =
141140767Sphk{
142140767Sphk  { {NULL, required_argument, NULL, '\0'},
143140767Sphk      'a', "KEYWORD", "Shared library control for HP/UX compatibility",
144140767Sphk      ONE_DASH },
145140767Sphk  { {"architecture", required_argument, NULL, 'A'},
146140767Sphk      'A', "ARCH", "Set architecture" , TWO_DASHES },
147140929Sphk  { {"format", required_argument, NULL, 'b'},
148140929Sphk      'b', "TARGET", "Specify target for following input files", TWO_DASHES },
149140929Sphk  { {"mri-script", required_argument, NULL, 'c'},
150140929Sphk      'c', "FILE", "Read MRI format linker script", TWO_DASHES },
151140929Sphk  { {"dc", no_argument, NULL, 'd'},
152140929Sphk      'd', NULL, "Force common symbols to be defined", ONE_DASH },
153140929Sphk  { {"dp", no_argument, NULL, 'd'},
154140929Sphk      '\0', NULL, NULL, ONE_DASH },
155171599Spjd  { {"entry", required_argument, NULL, 'e'},
156140929Sphk      'e', "ADDRESS", "Set start address", TWO_DASHES },
157140929Sphk  { {"export-dynamic", no_argument, NULL, OPTION_EXPORT_DYNAMIC},
158140929Sphk      'E', NULL, "Export all dynamic symbols", TWO_DASHES },
159140929Sphk  { {"auxiliary", required_argument, NULL, 'f'},
160140929Sphk      'f', "SHLIB", "Auxiliary filter for shared object symbol table",
161140929Sphk      TWO_DASHES },
162140929Sphk  { {"filter", required_argument, NULL, 'F'},
163140929Sphk      'F', "SHLIB", "Filter for shared object symbol table", TWO_DASHES },
164140929Sphk  { {NULL, no_argument, NULL, '\0'},
165140929Sphk      'g', NULL, "Ignored", ONE_DASH },
166140929Sphk  { {"gpsize", required_argument, NULL, 'G'},
167140929Sphk      'G', "SIZE", "Small data size (if no size, same as --shared)",
168140929Sphk      TWO_DASHES },
169140929Sphk  { {"soname", required_argument, NULL, OPTION_SONAME},
170140929Sphk      'h', "FILENAME", "Set internal name of shared library", ONE_DASH },
171140929Sphk  { {"library", required_argument, NULL, 'l'},
172140929Sphk      'l', "LIBNAME", "Search for library LIBNAME", TWO_DASHES },
173140929Sphk  { {"library-path", required_argument, NULL, 'L'},
174140929Sphk      'L', "DIRECTORY", "Add DIRECTORY to library search path", TWO_DASHES },
175140929Sphk  { {NULL, required_argument, NULL, '\0'},
176140929Sphk      'm', "EMULATION", "Set emulation", ONE_DASH },
177144610Sjeff  { {"print-map", no_argument, NULL, 'M'},
178140929Sphk      'M', NULL, "Print map file on standard output", TWO_DASHES },
179140929Sphk  { {"nmagic", no_argument, NULL, 'n'},
180140929Sphk      'n', NULL, "Do not page align data", TWO_DASHES },
1811541Srgrimes  { {"omagic", no_argument, NULL, 'N'},
1821541Srgrimes      'N', NULL, "Do not page align data, do not make text readonly",
1831541Srgrimes      TWO_DASHES },
18498604Salc  { {"output", required_argument, NULL, 'o'},
18598604Salc      'o', "FILE", "Set output file name", TWO_DASHES },
1861541Srgrimes  { {NULL, required_argument, NULL, '\0'},
1879507Sdg      'O', NULL, "Ignored", ONE_DASH },
18840286Sdg  { {"relocateable", no_argument, NULL, 'r'},
189194766Skib      'r', NULL, "Generate relocateable output", TWO_DASHES },
1901541Srgrimes  { {NULL, no_argument, NULL, '\0'},
1919456Sdg      'i', NULL, NULL, ONE_DASH },
1921541Srgrimes  { {"just-symbols", required_argument, NULL, 'R'},
1931541Srgrimes      'R', "FILE", "Just link symbols (if directory, same as --rpath)",
1941541Srgrimes      TWO_DASHES },
1951541Srgrimes  { {"strip-all", no_argument, NULL, 's'},
1961541Srgrimes      's', NULL, "Strip all symbols", TWO_DASHES },
1971541Srgrimes  { {"strip-debug", no_argument, NULL, 'S'},
1981827Sdg      'S', NULL, "Strip debugging symbols", TWO_DASHES },
1991541Srgrimes  { {"trace", no_argument, NULL, 't'},
2009411Sdg      't', NULL, "Trace file opens", TWO_DASHES },
2019411Sdg  { {"script", required_argument, NULL, 'T'},
2021541Srgrimes      'T', "FILE", "Read linker script", TWO_DASHES },
2039411Sdg  { {"undefined", required_argument, NULL, 'u'},
2049411Sdg      'u', "SYMBOL", "Start with undefined reference to SYMBOL", TWO_DASHES },
2059411Sdg  { {"version", no_argument, NULL, OPTION_VERSION},
206179159Sups      'v', NULL, "Print version information", TWO_DASHES },
207114074Salc  { {NULL, no_argument, NULL, '\0'},
208114074Salc      'V', NULL, "Print version and emulation information", ONE_DASH },
209181020Sjhb  { {"discard-all", no_argument, NULL, 'x'},
210114074Salc      'x', NULL, "Discard all local symbols", TWO_DASHES },
211137297Salc  { {"discard-locals", no_argument, NULL, 'X'},
212114074Salc      'X', NULL, "Discard temporary local symbols", TWO_DASHES },
2139507Sdg  { {"trace-symbol", required_argument, NULL, 'y'},
2145455Sdg      'y', "SYMBOL", "Trace mentions of SYMBOL", TWO_DASHES },
21532071Sdyson  { {NULL, required_argument, NULL, '\0'},
21632071Sdyson      'Y', "PATH", "Default search path for Solaris compatibility", ONE_DASH },
21732071Sdyson  { {NULL, required_argument, NULL, '\0'},
2189507Sdg      'z', "KEYWORD", "Ignored for Solaris compatibility", ONE_DASH },
2191541Srgrimes  { {"start-group", no_argument, NULL, '('},
220179159Sups      '(', NULL, "Start a group", TWO_DASHES },
2211541Srgrimes  { {"end-group", no_argument, NULL, ')'},
22240286Sdg      ')', NULL, "End a group", TWO_DASHES },
2231827Sdg  { {"assert", required_argument, NULL, OPTION_ASSERT},
22440286Sdg      '\0', "KEYWORD", "Ignored for SunOS compatibility", ONE_DASH },
2251549Srgrimes  { {"Bdynamic", no_argument, NULL, OPTION_CALL_SHARED},
2269507Sdg      '\0', NULL, "Link against shared libraries", ONE_DASH },
227179765Sups  { {"dy", no_argument, NULL, OPTION_CALL_SHARED},
228179765Sups      '\0', NULL, NULL, ONE_DASH },
229179159Sups  { {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
230179159Sups      '\0', NULL, NULL, ONE_DASH },
231179159Sups  { {"Bstatic", no_argument, NULL, OPTION_NON_SHARED},
232179765Sups      '\0', NULL, "Do not link against shared libraries", ONE_DASH },
233179159Sups  { {"dn", no_argument, NULL, OPTION_NON_SHARED},
234179159Sups      '\0', NULL, NULL, ONE_DASH },
235179159Sups  { {"non_shared", no_argument, NULL, OPTION_NON_SHARED},
2369507Sdg      '\0', NULL, NULL, ONE_DASH },
237179765Sups  { {"static", no_argument, NULL, OPTION_NON_SHARED},
238179765Sups      '\0', NULL, NULL, ONE_DASH },
23932286Sdyson  { {"Bsymbolic", no_argument, NULL, OPTION_SYMBOLIC},
240179765Sups      '\0', NULL, "Bind global references locally", ONE_DASH },
241179765Sups  { {"cref", no_argument, NULL, OPTION_CREF},
242143559Sjeff      '\0', NULL, "Output cross reference table", TWO_DASHES },
2439507Sdg  { {"defsym", required_argument, NULL, OPTION_DEFSYM},
2441541Srgrimes      '\0', "SYMBOL=EXPRESSION", "Define a symbol", TWO_DASHES },
2451541Srgrimes  { {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER},
246114774Salc      '\0', "PROGRAM", "Set the dynamic linker to use", TWO_DASHES },
247114774Salc  { {"EB", no_argument, NULL, OPTION_EB},
248114774Salc      '\0', NULL, "Link big-endian objects", ONE_DASH },
24912820Sphk  { {"EL", no_argument, NULL, OPTION_EL},
2509507Sdg      '\0', NULL, "Link little-endian objects", ONE_DASH },
2519507Sdg  { {"embedded-relocs", no_argument, NULL, OPTION_EMBEDDED_RELOCS},
2521541Srgrimes      '\0', NULL, "Generate embedded relocs", TWO_DASHES},
25379242Sdillon  { {"force-exe-suffix", no_argument, NULL, OPTION_FORCE_EXE_SUFFIX},
2541541Srgrimes      '\0', NULL, "Force generation of file with .exe suffix", TWO_DASHES},
2559507Sdg  { {"help", no_argument, NULL, OPTION_HELP},
2569507Sdg      '\0', NULL, "Print option help", TWO_DASHES },
2579507Sdg  { {"Map", required_argument, NULL, OPTION_MAP},
258114774Salc      '\0', "FILE", "Write a map file", ONE_DASH },
25933817Sdyson  { {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY},
2601541Srgrimes      '\0', NULL, "Use less memory and more disk I/O", TWO_DASHES },
2619507Sdg  { {"no-warn-mismatch", no_argument, NULL, OPTION_NO_WARN_MISMATCH},
26233109Sdyson      '\0', NULL, "Don't warn about mismatched input files", TWO_DASHES},
263137297Salc  { {"no-whole-archive", no_argument, NULL, OPTION_NO_WHOLE_ARCHIVE},
264137297Salc      '\0', NULL, "Turn off --whole-archive", TWO_DASHES },
265137297Salc  { {"noinhibit-exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
266137297Salc      '\0', NULL, "Create an output file even if errors occur", TWO_DASHES },
267171599Spjd  { {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
2689507Sdg      '\0', NULL, NULL, NO_HELP },
269140734Sphk  { {"oformat", required_argument, NULL, OPTION_OFORMAT},
2701549Srgrimes      '\0', "TARGET", "Specify target of output file", TWO_DASHES },
2711541Srgrimes  { {"qmagic", no_argument, NULL, OPTION_IGNORE},
27212820Sphk      '\0', NULL, "Ignored for Linux compatibility", ONE_DASH },
27312767Sdyson  { {"Qy", no_argument, NULL, OPTION_IGNORE},
2749507Sdg      '\0', NULL, "Ignored for SVR4 compatibility", ONE_DASH },
27512767Sdyson  { {"relax", no_argument, NULL, OPTION_RELAX},
2769507Sdg      '\0', NULL, "Relax branches on certain targets", TWO_DASHES },
2779507Sdg  { {"retain-symbols-file", required_argument, NULL,
2781541Srgrimes       OPTION_RETAIN_SYMBOLS_FILE},
2799507Sdg      '\0', "FILE", "Keep only symbols listed in FILE", TWO_DASHES },
28096572Sphk  { {"rpath", required_argument, NULL, OPTION_RPATH},
28112423Sphk      '\0', "PATH", "Set runtime shared library search path", ONE_DASH },
28210556Sdyson  { {"rpath-link", required_argument, NULL, OPTION_RPATH_LINK},
28311701Sdyson      '\0', "PATH", "Set link time shared library search path", ONE_DASH },
28411701Sdyson  { {"shared", no_argument, NULL, OPTION_SHARED},
28512914Sdyson      '\0', NULL, "Create a shared library", ONE_DASH },
286140723Sjeff  { {"Bshareable", no_argument, NULL, OPTION_SHARED }, /* FreeBSD.  */
2871541Srgrimes      '\0', NULL, NULL, ONE_DASH },
288116695Salc  { {"sort-common", no_argument, NULL, OPTION_SORT_COMMON},
28951340Sdillon      '\0', NULL, "Sort common symbols by size", TWO_DASHES },
29051340Sdillon  { {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
29151340Sdillon      '\0', NULL, NULL, NO_HELP },
29251340Sdillon  { {"split-by-file", no_argument, NULL, OPTION_SPLIT_BY_FILE},
293155384Sjeff      '\0', NULL, "Split output sections for each file", TWO_DASHES },
29432585Sdyson  { {"split-by-reloc", required_argument, NULL, OPTION_SPLIT_BY_RELOC},
2951541Srgrimes      '\0', "COUNT", "Split output sections every COUNT relocs", TWO_DASHES },
296155384Sjeff  { {"stats", no_argument, NULL, OPTION_STATS},
2975455Sdg      '\0', NULL, "Print memory usage statistics", TWO_DASHES },
2981541Srgrimes  { {"task-link", required_argument, NULL, OPTION_TASK_LINK},
299155384Sjeff      '\0', "SYMBOL", "Do task level linking", TWO_DASHES },
3004797Sdg  { {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT},
3011541Srgrimes      '\0', NULL, "Use same format as native linker", TWO_DASHES },
30211576Sdg  { {"Tbss", required_argument, NULL, OPTION_TBSS},
30310556Sdyson      '\0', "ADDRESS", "Set address of .bss section", ONE_DASH },
30412914Sdyson  { {"Tdata", required_argument, NULL, OPTION_TDATA},
30512914Sdyson      '\0', "ADDRESS", "Set address of .data section", ONE_DASH },
30612914Sdyson  { {"Ttext", required_argument, NULL, OPTION_TTEXT},
30712914Sdyson      '\0', "ADDRESS", "Set address of .text section", ONE_DASH },
30812914Sdyson  { {"Ur", no_argument, NULL, OPTION_UR},
30912914Sdyson      '\0', NULL, "Build global constructor/destructor tables", ONE_DASH },
31012914Sdyson  { {"verbose", no_argument, NULL, OPTION_VERBOSE},
311116695Salc      '\0', NULL, "Output lots of information during link", TWO_DASHES },
312140723Sjeff  { {"dll-verbose", no_argument, NULL, OPTION_VERBOSE}, /* Linux.  */
313119045Sphk      '\0', NULL, NULL, NO_HELP },
314140723Sjeff  { {"version-script", required_argument, NULL, OPTION_VERSION_SCRIPT },
315116695Salc      '\0', "FILE", "Read version information script", TWO_DASHES },
3168876Srgrimes  { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
3179507Sdg      '\0', NULL, "Warn about duplicate common symbols", TWO_DASHES },
31892029Seivind  { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},
31910576Sdyson      '\0', NULL, "Warn if global constructors/destructors are seen",
32012914Sdyson      TWO_DASHES },
32112914Sdyson  { {"warn-multiple-gp", no_argument, NULL, OPTION_WARN_MULTIPLE_GP},
32212914Sdyson      '\0', NULL, "Warn if the multiple GP values are used", TWO_DASHES },
32312914Sdyson  { {"warn-once", no_argument, NULL, OPTION_WARN_ONCE},
32412914Sdyson      '\0', NULL, "Warn only once per undefined symbol", TWO_DASHES },
32510669Sdyson  { {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN},
32612914Sdyson      '\0', NULL, "Warn if start of section changes due to alignment",
32712914Sdyson      TWO_DASHES },
32812914Sdyson  { {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE},
32912914Sdyson      '\0', NULL, "Include all objects from following archives", TWO_DASHES },
33099211Srobert  { {"wrap", required_argument, NULL, OPTION_WRAP},
33199211Srobert      '\0', "SYMBOL", "Use wrapper functions for SYMBOL", TWO_DASHES }
33299211Srobert};
33399211Srobert
33499211Srobert#define OPTION_COUNT ((int) (sizeof ld_options / sizeof ld_options[0]))
33512914Sdyson
33612914Sdysonvoid
33712914Sdysonparse_args (argc, argv)
33812914Sdyson     int argc;
33912914Sdyson     char **argv;
34012914Sdyson{
34112914Sdyson  int i, is, il;
34212914Sdyson  int ingroup = 0;
34312914Sdyson  char *default_dirlist = NULL;
34412914Sdyson  char shortopts[OPTION_COUNT * 3 + 2];
34512914Sdyson  struct option longopts[OPTION_COUNT + 1];
34610556Sdyson  int last_optind;
34710576Sdyson
3481541Srgrimes  /* Starting the short option string with '-' is for programs that
3491541Srgrimes     expect options and other ARGV-elements in any order and that care about
3501541Srgrimes     the ordering of the two.  We describe each non-option ARGV-element
3511541Srgrimes     as if it were the argument of an option with character code 1.  */
3529507Sdg  shortopts[0] = '-';
3531541Srgrimes  is = 1;
3541541Srgrimes  il = 0;
3551541Srgrimes  for (i = 0; i < OPTION_COUNT; i++)
3561541Srgrimes    {
3571541Srgrimes      if (ld_options[i].shortopt != '\0')
3581541Srgrimes	{
3591541Srgrimes	  shortopts[is] = ld_options[i].shortopt;
3601541Srgrimes	  ++is;
36112767Sdyson	  if (ld_options[i].opt.has_arg == required_argument
3621541Srgrimes	      || ld_options[i].opt.has_arg == optional_argument)
363116167Salc	    {
364116167Salc	      shortopts[is] = ':';
36538542Sluoqi	      ++is;
3661541Srgrimes	      if (ld_options[i].opt.has_arg == optional_argument)
367116167Salc		{
3681541Srgrimes		  shortopts[is] = ':';
369188386Skib		  ++is;
370116167Salc		}
371116167Salc	    }
372116167Salc	}
373116167Salc      if (ld_options[i].opt.name != NULL)
374116167Salc	{
375116167Salc	  longopts[il] = ld_options[i].opt;
3763374Sdg	  ++il;
377116167Salc	}
37838542Sluoqi    }
3799507Sdg  shortopts[is] = '\0';
380116167Salc  longopts[il].name = NULL;
381116167Salc
382116167Salc  /* The -G option is ambiguous on different platforms.  Sometimes it
383116167Salc     specifies the largest data size to put into the small data
38438542Sluoqi     section.  Sometimes it is equivalent to --shared.  Unfortunately,
385116167Salc     the first form takes an argument, while the second does not.
3861827Sdg
3871827Sdg     We need to permit the --shared form because on some platforms,
38887834Sdillon     such as Solaris, gcc -shared will pass -G to the linker.
38987834Sdillon
39087834Sdillon     To permit either usage, we look through the argument list.  If we
39187834Sdillon     find -G not followed by a number, we change it into --shared.
39287834Sdillon     This will work for most normal cases.  */
3931827Sdg  for (i = 1; i < argc; i++)
394116167Salc    if (strcmp (argv[i], "-G") == 0
395121230Salc	&& (i + 1 >= argc
396121230Salc	    || ! isdigit ((unsigned char) argv[i + 1][0])))
397121230Salc      argv[i] = (char *) "--shared";
398121230Salc
39970374Sdillon  last_optind = -1;
400121230Salc  while (1)
401121230Salc    {
402121230Salc      /* getopt_long_only is like getopt_long, but '-' as well as '--' can
403121230Salc	 indicate a long option.  */
404121230Salc      int longind;
40570374Sdillon      int optc;
406121230Salc
407193303Salc      /* Using last_optind lets us avoid calling ldemul_parse_args
408193303Salc	 multiple times on a single option, which would lead to
409193303Salc	 confusion in the internal static variables maintained by
410193303Salc	 getopt.  This could otherwise happen for an argument like
411193303Salc	 -nx, in which the -n is parsed as a single option, and we
412193303Salc	 loop around to pick up the -x.  */
413193303Salc      if (optind != last_optind)
414193303Salc	{
415193303Salc	  if (ldemul_parse_args (argc, argv))
416193303Salc	    continue;
417193303Salc	  last_optind = optind;
418193303Salc	}
419193303Salc
420193303Salc      optc = getopt_long_only (argc, argv, shortopts, longopts, &longind);
421193303Salc
422121230Salc      if (optc == -1)
423121230Salc	break;
424121230Salc      switch (optc)
425121230Salc	{
426121230Salc	default:
427173846Salc	  xexit (1);
428193303Salc	case 1:			/* File name.  */
429116167Salc	  lang_add_input_file (optarg, lang_input_file_is_file_enum,
430172875Salc			       (char *) NULL);
431172875Salc	  break;
432172875Salc
433172875Salc	case OPTION_IGNORE:
4341827Sdg	  break;
4351541Srgrimes	case 'a':
43612767Sdyson	  /* For HP/UX compatibility.  Actually -a shared should mean
43738542Sluoqi             ``use only shared libraries'' but, then, we don't
438116167Salc             currently support shared libraries on HP/UX anyhow.  */
4391541Srgrimes	  if (strcmp (optarg, "archive") == 0)
4401541Srgrimes	    config.dynamic_link = false;
4411549Srgrimes	  else if (strcmp (optarg, "shared") == 0
4421549Srgrimes		   || strcmp (optarg, "default") == 0)
4431549Srgrimes	    config.dynamic_link = true;
4441549Srgrimes	  else
445163359Salc	    einfo ("%P%F: unrecognized -a option `%s'\n", optarg);
446163359Salc	  break;
447163359Salc	case OPTION_ASSERT:
4481549Srgrimes	  /* FIXME: We just ignore these, but we should handle them.  */
4495455Sdg	  if (strcmp (optarg, "definitions") == 0)
4505455Sdg	    ;
45112767Sdyson	  else if (strcmp (optarg, "nodefinitions") == 0)
452146340Sbz	    ;
4531549Srgrimes	  else if (strcmp (optarg, "nosymbolic") == 0)
454138531Salc	    ;
4555455Sdg	  else if (strcmp (optarg, "pure-text") == 0)
4565455Sdg	    ;
457155384Sjeff	  else
45811701Sdyson	    einfo ("%P%F: unrecognized -assert option `%s'\n", optarg);
45911701Sdyson	  break;
4601549Srgrimes	case 'A':
4611549Srgrimes	  ldfile_add_arch (optarg);
4621549Srgrimes	  break;
4631549Srgrimes	case 'b':
464163359Salc	  lang_add_target (optarg);
465163359Salc	  break;
466163359Salc	case 'c':
467163359Salc	  ldfile_open_command_file (optarg);
46892029Seivind	  parser_input = input_mri_script;
4696151Sdg	  yyparse ();
4706151Sdg	  break;
4716151Sdg	case OPTION_CALL_SHARED:
4726151Sdg	  config.dynamic_link = true;
4736151Sdg	  break;
4741549Srgrimes	case OPTION_NON_SHARED:
475163359Salc	  config.dynamic_link = false;
4761549Srgrimes	  break;
4771549Srgrimes	case OPTION_CREF:
4781549Srgrimes	  command_line.cref = true;
47996755Strhodes	  link_info.notice_all = true;
4801549Srgrimes	  break;
48112820Sphk	case 'd':
4829507Sdg	  command_line.force_common_definition = true;
4839507Sdg	  break;
4841549Srgrimes	case OPTION_DEFSYM:
4851549Srgrimes	  lex_string = optarg;
486191935Salc	  lex_redirect (optarg);
487137726Sphk	  parser_input = input_defsym;
488137726Sphk	  parsing_defsym = 1;
4891549Srgrimes	  yyparse ();
490127926Salc	  parsing_defsym = 0;
491146340Sbz	  lex_string = NULL;
4921549Srgrimes	  break;
4935455Sdg	case OPTION_DYNAMIC_LINKER:
4941549Srgrimes	  command_line.interpreter = optarg;
4959507Sdg	  break;
496155384Sjeff	case OPTION_EB:
49711701Sdyson	  command_line.endian = ENDIAN_BIG;
49811701Sdyson	  break;
4991549Srgrimes	case OPTION_EL:
5001549Srgrimes	  command_line.endian = ENDIAN_LITTLE;
501137726Sphk	  break;
5021549Srgrimes	case OPTION_EMBEDDED_RELOCS:
503127926Salc	  command_line.embedded_relocs = true;
5041549Srgrimes	  break;
5051827Sdg	case OPTION_EXPORT_DYNAMIC:
50686092Sdillon	case 'E': /* HP/UX compatibility.  */
5071827Sdg	  command_line.export_dynamic = true;
508191935Salc	  break;
509191935Salc	case 'e':
5105455Sdg	  lang_add_entry (optarg, true);
5111549Srgrimes	  break;
51286092Sdillon	case 'f':
51386092Sdillon	  if (command_line.auxiliary_filters == NULL)
51486092Sdillon	    {
51586092Sdillon	      command_line.auxiliary_filters =
516163359Salc		(char **) xmalloc (2 * sizeof (char *));
517163359Salc	      command_line.auxiliary_filters[0] = optarg;
518163359Salc	      command_line.auxiliary_filters[1] = NULL;
51986092Sdillon	    }
5201827Sdg	  else
52142957Sdillon	    {
5221549Srgrimes	      int c;
5231827Sdg	      char **p;
52458345Sphk
525119092Sphk	      c = 0;
52684827Sjhb	      for (p = command_line.auxiliary_filters; *p != NULL; p++)
52784827Sjhb		++c;
52891406Sjhb	      command_line.auxiliary_filters =
52991406Sjhb		(char **) xrealloc (command_line.auxiliary_filters,
530127926Salc				    (c + 2) * sizeof (char *));
5316626Sdg	      command_line.auxiliary_filters[c] = optarg;
532137726Sphk	      command_line.auxiliary_filters[c + 1] = NULL;
5331549Srgrimes	    }
5341549Srgrimes	  break;
53570374Sdillon	case 'F':
536189595Sjhb	  command_line.filter_shlib = optarg;
5371827Sdg	  break;
5381827Sdg	case OPTION_FORCE_EXE_SUFFIX:
539121205Sphk	  command_line.force_exe_suffix = true;
540136927Sphk	  break;
5411549Srgrimes	case 'G':
542119092Sphk	  {
543119092Sphk	    char *end;
54458934Sphk	    g_switch_value = strtoul (optarg, &end, 0);
5451549Srgrimes	    if (*end)
5461549Srgrimes	      einfo ("%P%F: invalid number `%s'\n", optarg);
5471827Sdg	  }
5481827Sdg	  break;
5491827Sdg	case 'g':
550137726Sphk	  /* Ignore.  */
55142957Sdillon	  break;
5521827Sdg	case OPTION_HELP:
5531549Srgrimes	  help ();
554191935Salc	  xexit (0);
555127926Salc	  break;
556191935Salc	case 'L':
557191935Salc	  ldfile_add_library_path (optarg, true);
558191935Salc	  break;
559191935Salc	case 'l':
560191935Salc	  lang_add_input_file (optarg, lang_input_file_is_l_enum,
5611549Srgrimes			       (char *) NULL);
562127926Salc	  break;
5631827Sdg	case 'M':
5644207Sdg	  config.map_filename = "-";
5651549Srgrimes	  break;
5661549Srgrimes	case 'm':
5671549Srgrimes	  /* Ignore.  Was handled in a pre-parse.   */
5681549Srgrimes	  break;
5691549Srgrimes	case OPTION_MAP:
570139296Sphk	  config.map_filename = optarg;
5711549Srgrimes	  break;
57212820Sphk	case 'N':
5739507Sdg	  config.text_read_only = false;
5749507Sdg	  config.magic_demand_paged = false;
5751549Srgrimes	  config.dynamic_link = false;
5761549Srgrimes	  break;
5771541Srgrimes	case 'n':
5781541Srgrimes	  config.magic_demand_paged = false;
5795455Sdg	  config.dynamic_link = false;
5805455Sdg	  break;
581127926Salc	case OPTION_NO_KEEP_MEMORY:
58277398Sjhb	  link_info.keep_memory = false;
5831549Srgrimes	  break;
584121495Salc	case OPTION_NO_WARN_MISMATCH:
5851549Srgrimes	  command_line.warn_mismatch = false;
5861827Sdg	  break;
5871549Srgrimes	case OPTION_NOINHIBIT_EXEC:
5881549Srgrimes	  force_make_executable = true;
5891549Srgrimes	  break;
59012767Sdyson	case OPTION_NO_WHOLE_ARCHIVE:
5911549Srgrimes	  whole_archive = false;
5921549Srgrimes	  break;
5931549Srgrimes	case 'O':
59412767Sdyson	  /* FIXME "-O<non-digits> <value>" used to set the address of
59512767Sdyson	     section <non-digits>.  Was this for compatibility with
596121495Salc	     something, or can we create a new option to do that
597121495Salc	     (with a syntax similar to -defsym)?
5987178Sdg	     getopt can't handle two args to an option without kludges.  */
5995455Sdg	  break;
6005455Sdg	case 'o':
6015455Sdg	  lang_add_output (optarg, 0);
6025455Sdg	  break;
603127926Salc	case OPTION_OFORMAT:
6047178Sdg	  lang_add_output_format (optarg, (char *) NULL, (char *) NULL, 0);
605127926Salc	  break;
6061549Srgrimes	case 'i':
6071549Srgrimes	case 'r':
6081549Srgrimes	  link_info.relocateable = true;
60912767Sdyson	  config.build_constructors = false;
6101549Srgrimes	  config.magic_demand_paged = false;
6111549Srgrimes	  config.text_read_only = false;
6121549Srgrimes	  config.dynamic_link = false;
61383366Sjulian	  break;
6141549Srgrimes	case 'R':
61591406Sjhb	  /* The GNU linker traditionally uses -R to mean to include
6161549Srgrimes	     only the symbols from a file.  The Solaris linker uses -R
61779242Sdillon	     to set the path used by the runtime linker to find
6181549Srgrimes	     libraries.  This is the GNU linker -rpath argument.  We
6191549Srgrimes	     try to support both simultaneously by checking the file
6201549Srgrimes	     named.  If it is a directory, rather than a regular file,
6211549Srgrimes	     we assume -rpath was meant.  */
622127926Salc	  {
623127926Salc	    struct stat s;
6241549Srgrimes
625127926Salc	    if (stat (optarg, &s) >= 0
626121230Salc		&& ! S_ISDIR (s.st_mode))
627121230Salc	      {
6281549Srgrimes		lang_add_input_file (optarg,
629191935Salc				     lang_input_file_is_symbols_only_enum,
63039739Srvb				     (char *) NULL);
63139739Srvb		break;
6324207Sdg	      }
6331549Srgrimes	  }
6341549Srgrimes	  /* Fall through.  */
6351549Srgrimes	case OPTION_RPATH:
6361549Srgrimes	  if (command_line.rpath == NULL)
6371549Srgrimes	    command_line.rpath = buystring (optarg);
63810556Sdyson	  else
63933847Smsmith	    {
64076827Salfred	      char *buf;
64199211Srobert
64299211Srobert	      buf = xmalloc (strlen (command_line.rpath)
64333847Smsmith			     + strlen (optarg)
64433847Smsmith			     + 2);
64533847Smsmith	      sprintf (buf, "%s:%s", command_line.rpath, optarg);
64633847Smsmith	      free (command_line.rpath);
64712820Sphk	      command_line.rpath = buf;
6489507Sdg	    }
6499507Sdg	  break;
6501549Srgrimes	case OPTION_RPATH_LINK:
6519507Sdg	  if (command_line.rpath_link == NULL)
6529507Sdg	    command_line.rpath_link = buystring (optarg);
6531549Srgrimes	  else
65410556Sdyson	    {
65510556Sdyson	      char *buf;
65634403Smsmith
657140723Sjeff	      buf = xmalloc (strlen (command_line.rpath_link)
65832286Sdyson			     + strlen (optarg)
65910556Sdyson			     + 2);
660116279Salc	      sprintf (buf, "%s:%s", command_line.rpath_link, optarg);
661140723Sjeff	      free (command_line.rpath_link);
66234403Smsmith	      command_line.rpath_link = buf;
66376827Salfred	    }
66476827Salfred	  break;
665140723Sjeff	case OPTION_RELAX:
666116279Salc	  command_line.relax = true;
66733847Smsmith	  break;
66810556Sdyson	case OPTION_RETAIN_SYMBOLS_FILE:
66910556Sdyson	  add_keepsyms_file (optarg);
67033847Smsmith	  break;
67133847Smsmith	case 'S':
67233847Smsmith	  link_info.strip = strip_debugger;
67333847Smsmith	  break;
67433847Smsmith	case 's':
67533847Smsmith	  link_info.strip = strip_all;
67633847Smsmith	  break;
67710556Sdyson	case OPTION_SHARED:
67833847Smsmith	  link_info.shared = true;
67910556Sdyson	  break;
68010556Sdyson	case 'h':		/* Used on Solaris.  */
68133847Smsmith	case OPTION_SONAME:
68212767Sdyson	  command_line.soname = optarg;
68334206Sdyson	  break;
684146340Sbz	case OPTION_SORT_COMMON:
685163140Salc	  config.sort_common = true;
686137726Sphk	  break;
6876151Sdg	case OPTION_STATS:
6886151Sdg	  config.stats = true;
6897178Sdg	  break;
69033847Smsmith	case OPTION_SYMBOLIC:
691163210Salc	  link_info.symbolic = true;
6921549Srgrimes	  break;
69333847Smsmith	case 't':
69433847Smsmith	  trace_files = true;
69533847Smsmith	  break;
696137726Sphk	case 'T':
697137726Sphk	  ldfile_open_command_file (optarg);
698155384Sjeff	  parser_input = input_script;
69911701Sdyson	  yyparse ();
70011701Sdyson	  break;
7011549Srgrimes	case OPTION_TBSS:
7021549Srgrimes	  set_section_start (".bss", optarg);
7031549Srgrimes	  break;
7041827Sdg	case OPTION_TDATA:
7051549Srgrimes	  set_section_start (".data", optarg);
7061827Sdg	  break;
7071827Sdg	case OPTION_TTEXT:
7081549Srgrimes	  set_section_start (".text", optarg);
70912767Sdyson	  break;
7101827Sdg	case OPTION_TRADITIONAL_FORMAT:
7111549Srgrimes	  link_info.traditional_format = true;
7121887Sdg	  break;
7131549Srgrimes	case OPTION_TASK_LINK:
714163210Salc	  link_info.task_link = true;
715163210Salc	  /* Fall through - do an implied -r option.  */
716116512Salc	case OPTION_UR:
717100832Salc	  link_info.relocateable = true;
718100832Salc	  config.build_constructors = true;
719100832Salc	  config.magic_demand_paged = false;
72075692Salfred	  config.text_read_only = false;
721100832Salc	  config.dynamic_link = false;
722170292Sattilio	  break;
723170292Sattilio	case 'u':
724121495Salc	  ldlang_add_undef (optarg);
725121495Salc	  break;
726121495Salc	case OPTION_VERBOSE:
727163210Salc	  ldversion (1);
728163210Salc	  version_printed = true;
729163210Salc	  trace_file_tries = true;
730163210Salc	  break;
731163210Salc	case 'v':
732163210Salc	  ldversion (0);
733163210Salc	  version_printed = true;
734163210Salc	  break;
735163210Salc	case 'V':
7361549Srgrimes	  ldversion (1);
7371827Sdg	  version_printed = true;
7381827Sdg	  break;
7391827Sdg	case OPTION_VERSION:
7401827Sdg	  /* This output is intended to follow the GNU standards document.  */
7411827Sdg	  printf ("GNU ld %s\n", ld_program_version);
7421827Sdg	  printf ("Copyright 1997 Free Software Foundation, Inc.\n");
74338866Sbde	  printf ("\
744116512SalcThis program is free software; you may redistribute it under the terms of\n\
745100832Salcthe GNU General Public License.  This program has absolutely no warranty.\n");
746100832Salc	  {
747100832Salc	    ld_emulation_xfer_type **ptr = ld_emulations;
74875692Salfred
749100832Salc	    printf ("  Supported emulations:\n");
750116512Salc	    while (*ptr)
751170292Sattilio	      {
752170292Sattilio		printf ("   %s\n", (*ptr)->emulation_name);
7539507Sdg		ptr++;
7541549Srgrimes	      }
75545347Sjulian	  }
7561549Srgrimes	  xexit (0);
75745347Sjulian	  break;
75845347Sjulian	case OPTION_VERSION_SCRIPT:
75945347Sjulian	  /* This option indicates a small script that only specifies
7601549Srgrimes             version information.  Read it, but don't assume that
761121227Salc             we've seen a linker script.  */
76245347Sjulian	  {
763100832Salc	    boolean hold_had_script;
764100832Salc
7655455Sdg	    hold_had_script = had_script;
76675692Salfred	    ldfile_open_command_file (optarg);
767100832Salc	    had_script = hold_had_script;
768116512Salc	    parser_input = input_version_script;
7695455Sdg	    yyparse ();
770163140Salc	  }
771163140Salc	  break;
772192010Salc	case OPTION_WARN_COMMON:
773192010Salc	  config.warn_common = true;
774163140Salc	  break;
775163140Salc	case OPTION_WARN_CONSTRUCTORS:
776163140Salc	  config.warn_constructors = true;
777163140Salc	  break;
778163140Salc	case OPTION_WARN_MULTIPLE_GP:
779163140Salc	  config.warn_multiple_gp = true;
780163140Salc	  break;
781163140Salc	case OPTION_WARN_ONCE:
7821549Srgrimes	  config.warn_once = true;
78345347Sjulian	  break;
784121227Salc	case OPTION_WARN_SECTION_ALIGN:
7857178Sdg	  config.warn_section_align = true;
7865455Sdg	  break;
7875455Sdg	case OPTION_WHOLE_ARCHIVE:
7885455Sdg	  whole_archive = true;
78992029Seivind	  break;
7901549Srgrimes	case OPTION_WRAP:
7911549Srgrimes	  add_wrap (optarg);
7926151Sdg	  break;
7931549Srgrimes	case 'X':
79492029Seivind	  link_info.discard = discard_l;
795163359Salc	  break;
796163359Salc	case 'x':
797163359Salc	  link_info.discard = discard_all;
798163359Salc	  break;
799163359Salc	case 'Y':
800163359Salc	  if (strncmp (optarg, "P,", 2) == 0)
801163359Salc	    optarg += 2;
802163359Salc	  default_dirlist = xstrdup (optarg);
803163359Salc	  break;
804163359Salc	case 'y':
805163359Salc	  add_ysym (optarg);
8066151Sdg	  break;
807116512Salc	case 'z':
8089507Sdg	  /* We accept and ignore this option for Solaris
809146340Sbz             compatibility.  Actually, on Solaris, optarg is not
810146340Sbz             ignored.  Someday we should handle it correctly.  FIXME.  */
811106603Smux	  break;
812106603Smux	case OPTION_SPLIT_BY_RELOC:
813106603Smux	  config.split_by_reloc = atoi (optarg);
814106603Smux	  break;
8156151Sdg	case OPTION_SPLIT_BY_FILE:
816100832Salc	  config.split_by_file = true;
81775692Salfred	  break;
818100832Salc	case '(':
819116512Salc	  if (ingroup)
8206151Sdg	    {
8216151Sdg	      fprintf (stderr,
8226151Sdg		       "%s: may not nest groups (--help for usage)\n",
8231549Srgrimes		       program_name);
8246151Sdg	      xexit (1);
8259507Sdg	    }
826116512Salc	  lang_enter_group ();
827100832Salc	  ingroup = 1;
828100832Salc	  break;
82975692Salfred	case ')':
830100832Salc	  if (! ingroup)
831116512Salc	    {
8321549Srgrimes	      fprintf (stderr,
8339507Sdg		       "%s: group ended before it began (--help for usage)\n",
834116512Salc		       program_name);
835100832Salc	      xexit (1);
8369507Sdg	    }
83775692Salfred	  lang_leave_group ();
838100832Salc	  ingroup = 0;
839116512Salc	  break;
8406151Sdg
8416151Sdg	}
8426151Sdg    }
8431549Srgrimes
8446151Sdg  if (ingroup)
8451549Srgrimes    lang_leave_group ();
8461549Srgrimes
8471549Srgrimes  if (default_dirlist != NULL)
8481827Sdg    set_default_dirlist (default_dirlist);
8491827Sdg
8501549Srgrimes}
8511549Srgrimes
852163361Salc/* Add the (colon-separated) elements of DIRLIST_PTR to the
8531549Srgrimes   library search path.  */
8541549Srgrimes
8551549Srgrimesstatic void
8566151Sdgset_default_dirlist (dirlist_ptr)
8571549Srgrimes     char *dirlist_ptr;
8581549Srgrimes{
8591549Srgrimes  char *p;
86012767Sdyson
8611827Sdg  while (1)
8621549Srgrimes    {
8631549Srgrimes      p = strchr (dirlist_ptr, PATH_SEPARATOR);
8641549Srgrimes      if (p != NULL)
8651549Srgrimes	*p = '\0';
866134892Sphk      if (*dirlist_ptr != '\0')
8679507Sdg	ldfile_add_library_path (dirlist_ptr, true);
8689507Sdg      if (p == NULL)
869134892Sphk	break;
8701549Srgrimes      dirlist_ptr = p + 1;
8711549Srgrimes    }
87251340Sdillon}
8731549Srgrimes
874137726Sphkstatic void
875137726Sphkset_section_start (sect, valstr)
876136977Sphk     char *sect, *valstr;
877136977Sphk{
878136977Sphk  char *end;
87951340Sdillon  unsigned long val = strtoul (valstr, &end, 16);
88051340Sdillon  if (*end)
8811549Srgrimes    einfo ("%P%F: invalid hex number `%s'\n", valstr);
88242957Sdillon  lang_section_start (sect, exp_intop (val));
8835455Sdg}
8841887Sdg
8851549Srgrimes/* Print help messages for the options.  */
8861549Srgrimes
8871549Srgrimesstatic void
8881887Sdghelp ()
8891549Srgrimes{
8901549Srgrimes  int i;
89158345Sphk  const char **targets, **pp;
892119092Sphk
89384827Sjhb  printf ("Usage: %s [options] file...\n", program_name);
89484827Sjhb
89591406Sjhb  printf ("Options:\n");
89691406Sjhb  for (i = 0; i < OPTION_COUNT; i++)
8976626Sdg    {
898137726Sphk      if (ld_options[i].doc != NULL)
8991549Srgrimes	{
9001549Srgrimes	  boolean comma;
90170374Sdillon	  int len;
902189595Sjhb	  int j;
9031549Srgrimes
904170292Sattilio	  printf ("  ");
905170292Sattilio
9063612Sdg	  comma = false;
9071549Srgrimes	  len = 2;
908121205Sphk
909136927Sphk	  j = i;
9103612Sdg	  do
911119092Sphk	    {
9121549Srgrimes	      if (ld_options[j].shortopt != '\0'
91358934Sphk		  && ld_options[j].control != NO_HELP)
9141549Srgrimes		{
9151549Srgrimes		  printf ("%s-%c", comma ? ", " : "", ld_options[j].shortopt);
9161549Srgrimes		  len += (comma ? 2 : 0) + 2;
9171549Srgrimes		  if (ld_options[j].arg != NULL)
9181827Sdg		    {
9191549Srgrimes		      if (ld_options[j].opt.has_arg != optional_argument)
9205455Sdg			{
9211549Srgrimes			  printf (" ");
9221549Srgrimes			  ++len;
9231549Srgrimes			}
9241549Srgrimes		      printf ("%s", ld_options[j].arg);
925137726Sphk		      len += strlen (ld_options[j].arg);
92642957Sdillon		    }
9271549Srgrimes		  comma = true;
928116512Salc		}
929100736Salc	      ++j;
93034206Sdyson	    }
93134206Sdyson	  while (j < OPTION_COUNT && ld_options[j].doc == NULL);
93234206Sdyson
93334206Sdyson	  j = i;
93434206Sdyson	  do
93534206Sdyson	    {
93647239Sdt	      if (ld_options[j].opt.name != NULL
93745347Sjulian		  && ld_options[j].control != NO_HELP)
93845347Sjulian		{
93945347Sjulian		  printf ("%s-%s%s",
94034206Sdyson			  comma ? ", " : "",
941191478Salc			  ld_options[j].control == TWO_DASHES ? "-" : "",
942191478Salc			  ld_options[j].opt.name);
943191478Salc		  len += ((comma ? 2 : 0)
944191478Salc			  + 1
945191478Salc			  + (ld_options[j].control == TWO_DASHES ? 1 : 0)
946191478Salc			  + strlen (ld_options[j].opt.name));
94734206Sdyson		  if (ld_options[j].arg != NULL)
94845347Sjulian		    {
949192134Salc		      printf (" %s", ld_options[j].arg);
95045347Sjulian		      len += 1 + strlen (ld_options[j].arg);
95145347Sjulian		    }
95245347Sjulian		  comma = true;
95345347Sjulian		}
95445347Sjulian	      ++j;
955192134Salc	    }
95647239Sdt	  while (j < OPTION_COUNT && ld_options[j].doc == NULL);
957192134Salc
958192134Salc	  if (len >= 30)
959192134Salc	    {
960192134Salc	      printf ("\n");
96134206Sdyson	      len = 0;
96234206Sdyson	    }
9631549Srgrimes
9641827Sdg	  for (; len < 30; len++)
9651549Srgrimes	    putchar (' ');
9661827Sdg
9671827Sdg	  printf ("%s\n", ld_options[i].doc);
9681827Sdg	}
96958634Scharnier    }
9701827Sdg
9711549Srgrimes  printf ("%s: supported targets:", program_name);
9721827Sdg  targets = bfd_target_list ();
9731549Srgrimes  for (pp = targets; *pp != NULL; pp++)
9741827Sdg    printf (" %s", *pp);
9751827Sdg  free (targets);
9761549Srgrimes  printf ("\n");
9771549Srgrimes
978161125Salc  printf ("%s: supported emulations: ", program_name);
97934206Sdyson  ldemul_list_emulations (stdout);
98033109Sdyson  printf ("\n");
98134206Sdyson  printf ("\nReport bugs to bug-gnu-utils@gnu.org\n");
98238799Sdfr}
9831549Srgrimes