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