From 3bcf55573d377355c73846cc0b819c7d878d8e19 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 28 Feb 2003 01:32:31 +0000 Subject: [PATCH] * ldemul.c (ldemul_add_options, ldemul_handle_option): New functions. (ldemul_parse_args): Return bfd_boolean. Formatting. * ldemul.h (ldemul_add_options, ldemul_handle_option): Declare. (ldemul_parse_args): Adjust. (struct ld_emulation_xfer_struct): Add add_options and handle_option. Return bfd_boolean from parse_args. * lexsup.c (parse_args): Malloc shortopts, longopts and really_longopts. Call ldemul_add_options and ldemul_handle_option. * emultempl/aix.em (gld${EMULATION_NAME}_add_options): Split out from gld${EMULATION_NAME}_parse_args. (gld${EMULATION_NAME}_handle_option): Likewise. (ld_${EMULATION_NAME}_emulation): Adjust initializer. * emultempl/armcoff.em: As for aix.em, but remove parse_args. * emultempl/beos.em: Likewise. * emultempl/pe.em: Likewise. * emultempl/ticoff.em: Likewise. * emultempl/elf32.em: Likewise. Don't duplicate long options either. (gld${EMULATION_NAME}_add_sysroot): Prototype. * emultempl/armelf.em (PARSE_AND_LIST_LONGOPTS): Don't duplicate options. * emultempl/hppaelf.em (PARSE_AND_LIST_LONGOPTS): Likewise. * emultempl/ppc32elf.em (PARSE_AND_LIST_LONGOPTS): Likewise. * emultempl/ppc64elf.em (PARSE_AND_LIST_LONGOPTS): Likewise. * emultempl/armelf_oabi.em (ld_${EMULATION_NAME}_emulation): Adjust initializer. * emultempl/generic.em: Likewise. * emultempl/gld960.em: Likewise. * emultempl/gld960c.em: Likewise. * emultempl/linux.em: Likewise. * emultempl/lnk960.em: Likewise. * emultempl/m68kcoff.em: Likewise. * emultempl/mipsecoff.em: Likewise. * emultempl/sunos.em: Likewise. * emultempl/vanilla.em: Likewise. * emultempl/netbsd.em (gldnetbsd_before_parse): Prototype. --- ld/ChangeLog | 38 ++++++++++ ld/emultempl/aix.em | 80 +++++++++++--------- ld/emultempl/armcoff.em | 63 ++++++++-------- ld/emultempl/armelf.em | 6 +- ld/emultempl/armelf_oabi.em | 4 +- ld/emultempl/beos.em | 62 ++++++++-------- ld/emultempl/elf32.em | 92 +++++++++++------------ ld/emultempl/generic.em | 2 + ld/emultempl/gld960.em | 4 +- ld/emultempl/gld960c.em | 4 +- ld/emultempl/hppaelf.em | 4 - ld/emultempl/linux.em | 4 +- ld/emultempl/lnk960.em | 4 +- ld/emultempl/m68kcoff.em | 4 +- ld/emultempl/mipsecoff.em | 5 +- ld/emultempl/netbsd.em | 2 + ld/emultempl/pe.em | 143 ++++++++++++++++++------------------ ld/emultempl/ppc32elf.em | 2 - ld/emultempl/ppc64elf.em | 6 -- ld/emultempl/sunos.em | 4 +- ld/emultempl/ticoff.em | 64 ++++++++-------- ld/emultempl/vanilla.em | 5 +- ld/ldemul.c | 31 ++++++-- ld/ldemul.h | 21 +++++- ld/lexsup.c | 17 ++++- 25 files changed, 378 insertions(+), 293 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 0e78b3123bc..011549c9003 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,41 @@ +2003-02-28 Alan Modra + + * ldemul.c (ldemul_add_options, ldemul_handle_option): New functions. + (ldemul_parse_args): Return bfd_boolean. Formatting. + * ldemul.h (ldemul_add_options, ldemul_handle_option): Declare. + (ldemul_parse_args): Adjust. + (struct ld_emulation_xfer_struct): Add add_options and handle_option. + Return bfd_boolean from parse_args. + * lexsup.c (parse_args): Malloc shortopts, longopts and + really_longopts. Call ldemul_add_options and ldemul_handle_option. + * emultempl/aix.em (gld${EMULATION_NAME}_add_options): Split out from + gld${EMULATION_NAME}_parse_args. + (gld${EMULATION_NAME}_handle_option): Likewise. + (ld_${EMULATION_NAME}_emulation): Adjust initializer. + * emultempl/armcoff.em: As for aix.em, but remove parse_args. + * emultempl/beos.em: Likewise. + * emultempl/pe.em: Likewise. + * emultempl/ticoff.em: Likewise. + * emultempl/elf32.em: Likewise. Don't duplicate long options either. + (gld${EMULATION_NAME}_add_sysroot): Prototype. + * emultempl/armelf.em (PARSE_AND_LIST_LONGOPTS): Don't duplicate + options. + * emultempl/hppaelf.em (PARSE_AND_LIST_LONGOPTS): Likewise. + * emultempl/ppc32elf.em (PARSE_AND_LIST_LONGOPTS): Likewise. + * emultempl/ppc64elf.em (PARSE_AND_LIST_LONGOPTS): Likewise. + * emultempl/armelf_oabi.em (ld_${EMULATION_NAME}_emulation): Adjust + initializer. + * emultempl/generic.em: Likewise. + * emultempl/gld960.em: Likewise. + * emultempl/gld960c.em: Likewise. + * emultempl/linux.em: Likewise. + * emultempl/lnk960.em: Likewise. + * emultempl/m68kcoff.em: Likewise. + * emultempl/mipsecoff.em: Likewise. + * emultempl/sunos.em: Likewise. + * emultempl/vanilla.em: Likewise. + * emultempl/netbsd.em (gldnetbsd_before_parse): Prototype. + 2003-02-25 Alexandre Oliva * emultempl/elf32.em (gld${EMULATION_NAME}_add_sysroot): Fix diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em index b0a078a7549..910f831b897 100644 --- a/ld/emultempl/aix.em +++ b/ld/emultempl/aix.em @@ -9,7 +9,7 @@ cat >e${EMULATION_NAME}.c < AIX support by Ian Lance Taylor @@ -58,8 +58,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); -static int gld${EMULATION_NAME}_parse_args +static bfd_boolean gld${EMULATION_NAME}_parse_args PARAMS ((int, char **)); +static void gld${EMULATION_NAME}_add_options + PARAMS ((int, char **, int, struct option **, int, struct option **)); +static bfd_boolean gld${EMULATION_NAME}_handle_option + PARAMS ((int)); static void gld${EMULATION_NAME}_after_open PARAMS ((void)); static char *gld${EMULATION_NAME}_choose_target @@ -180,20 +184,7 @@ gld${EMULATION_NAME}_before_parse () /* Handle AIX specific options. */ -static int -gld${EMULATION_NAME}_parse_args (argc, argv) - int argc; - char **argv; -{ - int prevoptind = optind; - int prevopterr = opterr; - int indx; - int longind; - int optc; - bfd_signed_vma val; - const char *end; - - enum +enum { OPTION_IGNORE = 300, OPTION_AUTOIMP, @@ -218,6 +209,17 @@ gld${EMULATION_NAME}_parse_args (argc, argv) OPTION_NOLIBPATH, }; +static void +gld${EMULATION_NAME}_add_options (ns, shortopts, nl, longopts, nrl, really_longopts) + int ns; + char **shortopts; + int nl; + struct option **longopts; + int nrl ATTRIBUTE_UNUSED; + struct option **really_longopts ATTRIBUTE_UNUSED; +{ + static const char xtra_short[] = "D:H:KT:z"; + static const struct option xtra_long[] = { /* -binitfini has special handling in the linker backend. The native linker uses the arguemnts to generate a table of init and fini functions for the executable. The important use for this option is to support aix 4.2+ @@ -227,7 +229,6 @@ gld${EMULATION_NAME}_parse_args (argc, argv) the first symbol in the loader symbol table is __rtinit. The gnu linker generates this symbol and makes it the first loader symbol. */ - static const struct option longopts[] = { {"basis", no_argument, NULL, OPTION_IGNORE}, {"bautoimp", no_argument, NULL, OPTION_AUTOIMP}, {"bcomprld", no_argument, NULL, OPTION_IGNORE}, @@ -288,6 +289,20 @@ gld${EMULATION_NAME}_parse_args (argc, argv) -bnotypchk, -bnox, -bquiet, -bR, -brename, -breorder, -btypchk, -bx, -bX, -bxref. */ + *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short)); + memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short)); + *longopts = (struct option *) + xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long)); + memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long)); +} + +static bfd_boolean +gld${EMULATION_NAME}_parse_args (argc, argv) + int argc; + char **argv; +{ + int indx; + /* If the current option starts with -b, change the first : to an =. The AIX linker uses : to separate the option from the argument; changing it to = lets us treat it as a getopt option. */ @@ -308,22 +323,20 @@ gld${EMULATION_NAME}_parse_args (argc, argv) } } } + return FALSE; +} - - /* We add s and u so to the short options list so that -s and -u on - the command line do not match -static and -unix. */ - - opterr = 0; - optc = getopt_long_only (argc, argv, "-D:H:KT:zsu", longopts, &longind); - opterr = prevopterr; +static bfd_boolean +gld${EMULATION_NAME}_handle_option (optc) + int optc; +{ + bfd_signed_vma val; + const char *end; switch (optc) { - case 's': - case 'u': default: - optind = prevoptind; - return 0; + return FALSE; case 0: /* Long option which just sets a flag. */ @@ -358,10 +371,7 @@ gld${EMULATION_NAME}_parse_args (argc, argv) ignore the AIX option, because gcc passes it to the linker. */ val = bfd_scan_vma (optarg, &end, 0); if (*end != '\0') - { - optind = prevoptind; - return 0; - } + return FALSE; lang_section_start (".text", exp_intop (val)); break; @@ -552,7 +562,7 @@ gld${EMULATION_NAME}_parse_args (argc, argv) } - return 1; + return TRUE; } /* This is called when an input file can not be recognized as a BFD @@ -945,7 +955,7 @@ is_syscall (input, flag) /* Read an import or export file. For an import file, this is called by the before_allocation emulation routine. For an export file, - this is called by the parse_args emulation routine. */ + this is called by the handle_option emulation routine. */ static void gld${EMULATION_NAME}_read_file (filename, import) @@ -1391,6 +1401,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = { 0, /* place_orphan */ 0, /* set_symbols */ gld${EMULATION_NAME}_parse_args, + gld${EMULATION_NAME}_add_options, + gld${EMULATION_NAME}_handle_option, gld${EMULATION_NAME}_unrecognized_file, NULL, /* list_options */ NULL, /* recognized_file */ diff --git a/ld/emultempl/armcoff.em b/ld/emultempl/armcoff.em index 73828eb2f62..11566581e03 100644 --- a/ld/emultempl/armcoff.em +++ b/ld/emultempl/armcoff.em @@ -4,7 +4,7 @@ cat >e${EMULATION_NAME}.c < Set the entry point to be Thumb symbol \n")); } -static int -gld${EMULATION_NAME}_parse_args (argc, argv) - int argc; - char ** argv; +static bfd_boolean +gld${EMULATION_NAME}_handle_option (optc) + int optc; { - int longind; - int optc; - int prevoptind = optind; - int prevopterr = opterr; - int wanterror; - static int lastoptind = -1; - - if (lastoptind != optind) - opterr = 0; - - wanterror = opterr; - lastoptind = optind; - - optc = getopt_long_only (argc, argv, "-", longopts, & longind); - opterr = prevopterr; - switch (optc) { default: - if (wanterror) - xexit (1); - optind = prevoptind; - return 0; + return FALSE; case OPTION_SUPPORT_OLD_CODE: support_old_code = 1; @@ -110,7 +105,7 @@ gld${EMULATION_NAME}_parse_args (argc, argv) break; } - return 1; + return TRUE; } static void @@ -286,7 +281,9 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = NULL, /* open dynamic archive */ NULL, /* place orphan */ NULL, /* set symbols */ - gld${EMULATION_NAME}_parse_args, + NULL, /* parse_args */ + gld${EMULATION_NAME}_add_options, + gld${EMULATION_NAME}_handle_option, NULL, /* unrecognised file */ gld${EMULATION_NAME}_list_options, NULL, /* recognized file */ diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index c0b88f8ea7b..4a63e697e70 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -1,5 +1,5 @@ # This shell script emits a C file. -*- C -*- -# Copyright 1991, 1993, 1996, 1997, 1998, 1999, 2000, 2002 +# Copyright 1991, 1993, 1996, 1997, 1998, 1999, 2000, 2002, 2003 # Free Software Foundation, Inc. # # This file is part of GLD, the Gnu Linker. @@ -195,11 +195,7 @@ PARSE_AND_LIST_PROLOGUE=' PARSE_AND_LIST_SHORTOPTS=p -# Note we have duplicate entries for no-pipeline-knowledge in order -# to prevent getopt_long_only from thinking that -n is a unique -# abbreviation for --no-pipeline-knowledge. PARSE_AND_LIST_LONGOPTS=' - { "no-pipeline-knowledge", no_argument, NULL, '\'p\''}, { "no-pipeline-knowledge", no_argument, NULL, '\'p\''}, { "thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY}, ' diff --git a/ld/emultempl/armelf_oabi.em b/ld/emultempl/armelf_oabi.em index 647ada3b526..555b947e383 100644 --- a/ld/emultempl/armelf_oabi.em +++ b/ld/emultempl/armelf_oabi.em @@ -4,7 +4,7 @@ cat >e${EMULATION_NAME}.c <e${EMULATION_NAME}.c < #include "elf/common.h" +#include "getopt.h" static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); @@ -444,6 +445,8 @@ if [ "x${USE_LIBPATH}" = xyes ] ; then /* Add the sysroot to every entry in a colon-separated path. */ +static char * gld${EMULATION_NAME}_add_sysroot PARAMS ((const char *)); + static char * gld${EMULATION_NAME}_add_sysroot (path) const char *path; @@ -1514,8 +1517,6 @@ fi if test -n "$PARSE_AND_LIST_ARGS_CASES" -o x"$GENERATE_SHLIB_SCRIPT" = xyes; then -if test x"$LDEMUL_PARSE_ARGS" != xgld"$EMULATION_NAME"_parse_args; then - if test -n "$PARSE_AND_LIST_PROLOGUE" ; then cat >>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <e${EMULATION_NAME}.c <e${EMULATION_NAME}.c <e${EMULATION_NAME}.c < Linux support by Eric Youngdale @@ -218,6 +218,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = NULL, /* place orphan */ NULL, /* set symbols */ NULL, /* parse args */ + NULL, /* add_options */ + NULL, /* handle_option */ NULL, /* unrecognized file */ NULL, /* list options */ NULL, /* recognized file */ diff --git a/ld/emultempl/lnk960.em b/ld/emultempl/lnk960.em index b000fa976ed..ba0fe93b6f6 100644 --- a/ld/emultempl/lnk960.em +++ b/ld/emultempl/lnk960.em @@ -2,7 +2,7 @@ # It does some substitutions. cat >e${EMULATION_NAME}.c <e${EMULATION_NAME}.c <, based on generic.em by Steve Chamberlain , embedded relocs code based on mipsecoff.em by Ian Lance Taylor . @@ -237,6 +237,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = NULL, /* place orphan */ NULL, /* set symbols */ NULL, /* parse args */ + NULL, /* add_options */ + NULL, /* handle_option */ NULL, /* unrecognized file */ NULL, /* list options */ NULL, /* recognized file */ diff --git a/ld/emultempl/mipsecoff.em b/ld/emultempl/mipsecoff.em index 9fda644eaa0..6e417ed52c6 100644 --- a/ld/emultempl/mipsecoff.em +++ b/ld/emultempl/mipsecoff.em @@ -9,7 +9,8 @@ cat >e${EMULATION_NAME}.c < based on generic.em. This file is part of GLD, the Gnu Linker. @@ -252,6 +253,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = NULL, /* place orphan */ NULL, /* set symbols */ NULL, /* parse args */ + NULL, /* add_options */ + NULL, /* handle_option */ NULL, /* unrecognized file */ NULL, /* list options */ NULL, /* recognized file */ diff --git a/ld/emultempl/netbsd.em b/ld/emultempl/netbsd.em index 4ad564b242d..891a87941fc 100644 --- a/ld/emultempl/netbsd.em +++ b/ld/emultempl/netbsd.em @@ -1,5 +1,7 @@ LDEMUL_BEFORE_PARSE=gldnetbsd_before_parse cat >>e${EMULATION_NAME}.c <e${EMULATION_NAME}.c < SunOS shared library support by Ian Lance Taylor @@ -1047,6 +1047,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = NULL, /* place orphan */ gld${EMULATION_NAME}_set_symbols, NULL, /* parse args */ + NULL, /* add_options */ + NULL, /* handle_option */ NULL, /* unrecognized file */ NULL, /* list options */ NULL, /* recognized file */ diff --git a/ld/emultempl/ticoff.em b/ld/emultempl/ticoff.em index 363cb865c3d..620877ad144 100644 --- a/ld/emultempl/ticoff.em +++ b/ld/emultempl/ticoff.em @@ -3,7 +3,7 @@ (echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-) cat >>e${EMULATION_NAME}.c <e${EMULATION_NAME}.c <add_options) + (*ld_emulation->add_options) (ns, shortopts, nl, longopts, + nrl, really_longopts); +} + +bfd_boolean +ldemul_handle_option (optc) + int optc; +{ + if (ld_emulation->handle_option) + return (*ld_emulation->handle_option) (optc); + return FALSE; +} + +bfd_boolean ldemul_parse_args (argc, argv) int argc; char **argv; { /* Try and use the emulation parser if there is one. */ if (ld_emulation->parse_args) - { - return ld_emulation->parse_args (argc, argv); - } - return 0; + return (*ld_emulation->parse_args) (argc, argv); + return TRUE; } /* Let the emulation code handle an unrecognized file. */ diff --git a/ld/ldemul.h b/ld/ldemul.h index a048b72ddc8..548a7047ef8 100644 --- a/ld/ldemul.h +++ b/ld/ldemul.h @@ -51,8 +51,12 @@ extern void ldemul_create_output_section_statements PARAMS ((void)); extern bfd_boolean ldemul_place_orphan PARAMS ((struct lang_input_statement_struct *, asection *)); -extern int ldemul_parse_args +extern bfd_boolean ldemul_parse_args PARAMS ((int, char **)); +extern void ldemul_add_options + PARAMS ((int, char **, int, struct option **, int, struct option **)); +extern bfd_boolean ldemul_handle_option + PARAMS ((int)); extern bfd_boolean ldemul_unrecognized_file PARAMS ((struct lang_input_statement_struct *)); extern bfd_boolean ldemul_recognized_file @@ -142,9 +146,18 @@ typedef struct ld_emulation_xfer_struct { reading the script. Used to initialize symbols used in the script. */ void (*set_symbols) PARAMS ((void)); - /* Run to parse args which the base linker doesn't - understand. Return non zero on sucess. */ - int (*parse_args) PARAMS ((int, char **)); + /* Parse args which the base linker doesn't understand. + Return TRUE on success. */ + bfd_boolean (*parse_args) PARAMS ((int, char **)); + + /* Hook to add options to parameters passed by the base linker to + getopt_long and getopt_long_only calls. */ + void (*add_options) + PARAMS ((int, char **, int, struct option **, int, struct option **)); + + /* Companion to the above to handle an option. Returns TRUE if it is + one of our options. */ + bfd_boolean (*handle_option) PARAMS ((int)); /* Run to handle files which are not recognized as object files or archives. Return TRUE if the file was handled. */ diff --git a/ld/lexsup.c b/ld/lexsup.c index 8102f4ef12a..b6c2fd87ace 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -467,11 +467,17 @@ parse_args (argc, argv) int is, il, irl; int ingroup = 0; char *default_dirlist = NULL; - char shortopts[OPTION_COUNT * 3 + 2]; - struct option longopts[OPTION_COUNT + 1]; - struct option really_longopts[OPTION_COUNT + 1]; + char *shortopts; + struct option *longopts; + struct option *really_longopts; int last_optind; + shortopts = (char *) xmalloc (OPTION_COUNT * 3 + 2); + longopts = (struct option *) xmalloc (sizeof (*longopts) + * (OPTION_COUNT + 1)); + really_longopts = (struct option *) xmalloc (sizeof (*really_longopts) + * (OPTION_COUNT + 1)); + /* Starting the short option string with '-' is for programs that expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element @@ -516,6 +522,8 @@ parse_args (argc, argv) longopts[il].name = NULL; really_longopts[irl].name = NULL; + ldemul_add_options (is, &shortopts, il, &longopts, irl, &really_longopts); + /* The -G option is ambiguous on different platforms. Sometimes it specifies the largest data size to put into the small data section. Sometimes it is equivalent to --shared. Unfortunately, @@ -586,6 +594,9 @@ parse_args (argc, argv) optc = getopt_long (argc, argv, "-", really_longopts, &longind); } + if (ldemul_handle_option (optc)) + continue; + if (optc == -1) break; -- 2.30.2