binutils-gdb/ld/lexsup.c

1436 lines
48 KiB
C
Raw Normal View History

1999-05-03 09:29:11 +02:00
/* Parse options for the GNU linker.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003
1999-05-03 09:29:11 +02:00
Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
1999-05-03 09:29:11 +02:00
GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
1999-05-03 09:29:11 +02:00
GLD is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
1999-05-03 09:29:11 +02:00
You should have received a copy of the GNU General Public License
along with GLD; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
1999-05-03 09:29:11 +02:00
#include "bfd.h"
#include "sysdep.h"
#include "libiberty.h"
#include <stdio.h>
#include <string.h>
#include "safe-ctype.h"
1999-05-03 09:29:11 +02:00
#include "getopt.h"
#include "bfdlink.h"
#include "ld.h"
#include "ldmain.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldlang.h"
#include <ldgram.h>
1999-05-03 09:29:11 +02:00
#include "ldlex.h"
#include "ldfile.h"
#include "ldver.h"
#include "ldemul.h"
#include "demangle.h"
1999-05-03 09:29:11 +02:00
#ifndef PATH_SEPARATOR
#if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN32__))
#define PATH_SEPARATOR ';'
#else
#define PATH_SEPARATOR ':'
#endif
#endif
/* Somewhere above, sys/stat.h got included . . . . */
1999-05-03 09:29:11 +02:00
#if !defined(S_ISDIR) && defined(S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
2003-06-28 07:28:54 +02:00
static void set_default_dirlist (char *);
static void set_section_start (char *, char *);
static void help (void);
1999-05-03 09:29:11 +02:00
/* Non-zero if we are processing a --defsym from the command line. */
int parsing_defsym = 0;
/* Codes used for the long options with no short synonyms. 150 isn't
special; it's just an arbitrary non-ASCII char value. */
2003-08-20 10:37:19 +02:00
enum option_values
{
OPTION_ASSERT = 150,
OPTION_CALL_SHARED,
OPTION_CREF,
OPTION_DEFSYM,
OPTION_DEMANGLE,
OPTION_DYNAMIC_LINKER,
OPTION_EB,
OPTION_EL,
OPTION_EMBEDDED_RELOCS,
OPTION_EXPORT_DYNAMIC,
OPTION_HELP,
OPTION_IGNORE,
OPTION_MAP,
OPTION_NO_DEMANGLE,
OPTION_NO_KEEP_MEMORY,
OPTION_NO_WARN_MISMATCH,
OPTION_NOINHIBIT_EXEC,
OPTION_NON_SHARED,
OPTION_NO_WHOLE_ARCHIVE,
OPTION_OFORMAT,
OPTION_RELAX,
OPTION_RETAIN_SYMBOLS_FILE,
OPTION_RPATH,
OPTION_RPATH_LINK,
OPTION_SHARED,
OPTION_SONAME,
OPTION_SORT_COMMON,
OPTION_STATS,
OPTION_SYMBOLIC,
OPTION_TASK_LINK,
OPTION_TBSS,
OPTION_TDATA,
OPTION_TTEXT,
OPTION_TRADITIONAL_FORMAT,
OPTION_UR,
OPTION_VERBOSE,
OPTION_VERSION,
OPTION_VERSION_SCRIPT,
OPTION_VERSION_EXPORTS_SECTION,
OPTION_WARN_COMMON,
OPTION_WARN_CONSTRUCTORS,
OPTION_WARN_FATAL,
OPTION_WARN_MULTIPLE_GP,
OPTION_WARN_ONCE,
OPTION_WARN_SECTION_ALIGN,
OPTION_SPLIT_BY_RELOC,
OPTION_SPLIT_BY_FILE ,
OPTION_WHOLE_ARCHIVE,
OPTION_WRAP,
OPTION_FORCE_EXE_SUFFIX,
OPTION_GC_SECTIONS,
OPTION_NO_GC_SECTIONS,
OPTION_CHECK_SECTIONS,
OPTION_NO_CHECK_SECTIONS,
OPTION_MPC860C0,
OPTION_NO_UNDEFINED,
OPTION_INIT,
OPTION_FINI,
OPTION_SECTION_START,
OPTION_UNIQUE,
OPTION_TARGET_HELP,
OPTION_ALLOW_SHLIB_UNDEFINED,
OPTION_NO_ALLOW_SHLIB_UNDEFINED,
OPTION_ALLOW_MULTIPLE_DEFINITION,
OPTION_NO_UNDEFINED_VERSION,
OPTION_DISCARD_NONE,
OPTION_SPARE_DYNAMIC_TAGS,
OPTION_NO_DEFINE_COMMON,
OPTION_NOSTDLIB,
OPTION_NO_OMAGIC,
OPTION_STRIP_DISCARDED,
OPTION_NO_STRIP_DISCARDED,
OPTION_ACCEPT_UNKNOWN_INPUT_ARCH,
OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH,
OPTION_PIE,
OPTION_UNRESOLVED_SYMBOLS,
OPTION_WARN_UNRESOLVED_SYMBOLS,
OPTION_ERROR_UNRESOLVED_SYMBOLS
};
1999-05-03 09:29:11 +02:00
/* The long options. This structure is used for both the option
parsing and the help text. */
struct ld_option
{
1999-05-03 09:29:11 +02:00
/* The long option information. */
struct option opt;
/* The short option with the same meaning ('\0' if none). */
char shortopt;
/* The name of the argument (NULL if none). */
const char *arg;
/* The documentation string. If this is NULL, this is a synonym for
the previous option. */
const char *doc;
enum {
/* Use one dash before long option name. */
ONE_DASH,
/* Use two dashes before long option name. */
TWO_DASHES,
/* Only accept two dashes before the long option name.
This is an overloading of the use of this enum, since originally it
was only intended to tell the --help display function how to display
the long option name. This feature was added in order to resolve
the confusion about the -omagic command line switch. Is it setting
the output file name to "magic" or is it setting the NMAGIC flag on
the output ? It has been decided that it is setting the output file
name, and that if you want to set the NMAGIC flag you should use -N
or --omagic. */
EXACTLY_TWO_DASHES,
/* Don't mention this option in --help output. */
NO_HELP
} control;
1999-05-03 09:29:11 +02:00
};
static const struct ld_option ld_options[] =
{
1999-05-03 09:29:11 +02:00
{ {NULL, required_argument, NULL, '\0'},
'a', N_("KEYWORD"), N_("Shared library control for HP/UX compatibility"),
ONE_DASH },
{ {"architecture", required_argument, NULL, 'A'},
'A', N_("ARCH"), N_("Set architecture") , TWO_DASHES },
{ {"format", required_argument, NULL, 'b'},
'b', N_("TARGET"), N_("Specify target for following input files"), TWO_DASHES },
{ {"mri-script", required_argument, NULL, 'c'},
'c', N_("FILE"), N_("Read MRI format linker script"), TWO_DASHES },
{ {"dc", no_argument, NULL, 'd'},
'd', NULL, N_("Force common symbols to be defined"), ONE_DASH },
{ {"dp", no_argument, NULL, 'd'},
'\0', NULL, NULL, ONE_DASH },
{ {"entry", required_argument, NULL, 'e'},
'e', N_("ADDRESS"), N_("Set start address"), TWO_DASHES },
{ {"export-dynamic", no_argument, NULL, OPTION_EXPORT_DYNAMIC},
'E', NULL, N_("Export all dynamic symbols"), TWO_DASHES },
{ {"EB", no_argument, NULL, OPTION_EB},
'\0', NULL, N_("Link big-endian objects"), ONE_DASH },
{ {"EL", no_argument, NULL, OPTION_EL},
'\0', NULL, N_("Link little-endian objects"), ONE_DASH },
{ {"auxiliary", required_argument, NULL, 'f'},
'f', N_("SHLIB"), N_("Auxiliary filter for shared object symbol table"),
TWO_DASHES },
{ {"filter", required_argument, NULL, 'F'},
'F', N_("SHLIB"), N_("Filter for shared object symbol table"), TWO_DASHES },
{ {NULL, no_argument, NULL, '\0'},
'g', NULL, N_("Ignored"), ONE_DASH },
{ {"gpsize", required_argument, NULL, 'G'},
'G', N_("SIZE"), N_("Small data size (if no size, same as --shared)"),
TWO_DASHES },
{ {"soname", required_argument, NULL, OPTION_SONAME},
'h', N_("FILENAME"), N_("Set internal name of shared library"), ONE_DASH },
2001-05-22 16:00:18 +02:00
{ {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER},
'I', N_("PROGRAM"), N_("Set PROGRAM as the dynamic linker to use"), TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"library", required_argument, NULL, 'l'},
'l', N_("LIBNAME"), N_("Search for library LIBNAME"), TWO_DASHES },
{ {"library-path", required_argument, NULL, 'L'},
'L', N_("DIRECTORY"), N_("Add DIRECTORY to library search path"), TWO_DASHES },
{ {NULL, required_argument, NULL, '\0'},
'm', N_("EMULATION"), N_("Set emulation"), ONE_DASH },
{ {"print-map", no_argument, NULL, 'M'},
'M', NULL, N_("Print map file on standard output"), TWO_DASHES },
{ {"nmagic", no_argument, NULL, 'n'},
'n', NULL, N_("Do not page align data"), TWO_DASHES },
{ {"omagic", no_argument, NULL, 'N'},
'N', NULL, N_("Do not page align data, do not make text readonly"),
EXACTLY_TWO_DASHES },
{ {"no-omagic", no_argument, NULL, OPTION_NO_OMAGIC},
'\0', NULL, N_("Page align data, make text readonly"), EXACTLY_TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"output", required_argument, NULL, 'o'},
'o', N_("FILE"), N_("Set output file name"), EXACTLY_TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {NULL, required_argument, NULL, '\0'},
'O', NULL, N_("Optimize output file"), ONE_DASH },
{ {"Qy", no_argument, NULL, OPTION_IGNORE},
'\0', NULL, N_("Ignored for SVR4 compatibility"), ONE_DASH },
{ {"emit-relocs", no_argument, NULL, 'q'},
'q', NULL, "Generate relocations in final output", TWO_DASHES },
2003-06-25 08:40:27 +02:00
{ {"relocatable", no_argument, NULL, 'r'},
'r', NULL, N_("Generate relocatable output"), TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {NULL, no_argument, NULL, '\0'},
'i', NULL, NULL, ONE_DASH },
{ {"just-symbols", required_argument, NULL, 'R'},
'R', N_("FILE"), N_("Just link symbols (if directory, same as --rpath)"),
TWO_DASHES },
{ {"strip-all", no_argument, NULL, 's'},
's', NULL, N_("Strip all symbols"), TWO_DASHES },
{ {"strip-debug", no_argument, NULL, 'S'},
'S', NULL, N_("Strip debugging symbols"), TWO_DASHES },
{ {"strip-discarded", no_argument, NULL, OPTION_STRIP_DISCARDED},
'\0', NULL, N_("Strip symbols in discarded sections"), TWO_DASHES },
{ {"no-strip-discarded", no_argument, NULL, OPTION_NO_STRIP_DISCARDED},
'\0', NULL, N_("Do not strip symbols in discarded sections"), TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"trace", no_argument, NULL, 't'},
't', NULL, N_("Trace file opens"), TWO_DASHES },
{ {"script", required_argument, NULL, 'T'},
'T', N_("FILE"), N_("Read linker script"), TWO_DASHES },
{ {"undefined", required_argument, NULL, 'u'},
'u', N_("SYMBOL"), N_("Start with undefined reference to SYMBOL"), TWO_DASHES },
2001-01-14 05:36:35 +01:00
{ {"unique", optional_argument, NULL, OPTION_UNIQUE},
'\0', N_("[=SECTION]"), N_("Don't merge input [SECTION | orphan] sections"), TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"Ur", no_argument, NULL, OPTION_UR},
'\0', NULL, N_("Build global constructor/destructor tables"), ONE_DASH },
{ {"version", no_argument, NULL, OPTION_VERSION},
'v', NULL, N_("Print version information"), TWO_DASHES },
{ {NULL, no_argument, NULL, '\0'},
'V', NULL, N_("Print version and emulation information"), ONE_DASH },
{ {"discard-all", no_argument, NULL, 'x'},
'x', NULL, N_("Discard all local symbols"), TWO_DASHES },
{ {"discard-locals", no_argument, NULL, 'X'},
bfd/ * libbfd-in.h (_bfd_merge_section): New. (_bfd_write_merged_section): New. (_bfd_merged_section_offset): New. * libbfd.h: Rebuilt. * linker.c (_bfd_generic_link_output_symbols): Handle discard_sec_merge. * aoutx.h (aout_link_write_symbols): Likewise. * pdp11.c (aout_link_write_symbols): Likewise. * elflink.h (elf_link_add_object_symbols): Call _bfd_merge_section. (elf_bfd_final_link): Adjust global symbols pointing into SEC_MERGE sections. (elf_link_sec_merge_syms): New. (elf_link_input_bfd): Call _bfd_merged_section_offset and _bfd_write_merged_section. Handle discard_sec_merge. * elf-bfd.h (struct elf_link_hash_table): Add merge_info field. (struct bfd_elf_section_data): Likewise. * elf.c (_bfd_elf_make_section_from_shdr): Set SEC_MERGE and SEC_STRINGS section flags and entsize from their ELF counterparts. (_bfd_elf_link_hash_table_init): Initialize merge_info. (elf_fake_sections): Set SHF_MERGE, SHF_STRINGS and sh_entsize from their BFD counterparts. * merge.c: New file. * Makefile.am: Add strtab.lo. * Makefile.in: Rebuilt. include/ * bfdlink.h (bfd_link_discard): Add discard_sec_merge. gas/ * config/obj-elf.c (obj_elf_change_section): Add entsize argument, handle SHF_MERGE and SHF_STRINGS. (obj_elf_parse_section_letters): Set SHF_MERGE and SHF_STRINGS. (obj_elf_section): Allow additional argument specifying entity size. * write.c (adjust_reloc_syms): Keep relocations against local symbols in SEC_MERGE sections. ld/ * ldmain.c (main): Default to discard_sec_merge. * lexsup.c (OPTION_DISCARD_NONE): Define. (ld_options): Add --discard-none. (parse_args): Handle OPTION_DISCARD_NONE. * ldlang.c (wild_doit): SEC_MERGE should be set in the output section only if SEC_MERGE and SEC_STRINGS flags and entsize of all its input sections match.
2001-04-13 02:34:36 +02:00
'X', NULL, N_("Discard temporary local symbols (default)"), TWO_DASHES },
{ {"discard-none", no_argument, NULL, OPTION_DISCARD_NONE},
'\0', NULL, N_("Don't discard any local symbols"), TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"trace-symbol", required_argument, NULL, 'y'},
'y', N_("SYMBOL"), N_("Trace mentions of SYMBOL"), TWO_DASHES },
{ {NULL, required_argument, NULL, '\0'},
'Y', N_("PATH"), N_("Default search path for Solaris compatibility"), ONE_DASH },
{ {"start-group", no_argument, NULL, '('},
'(', NULL, N_("Start a group"), TWO_DASHES },
{ {"end-group", no_argument, NULL, ')'},
')', NULL, N_("End a group"), TWO_DASHES },
{ {"accept-unknown-input-arch", no_argument, NULL, OPTION_ACCEPT_UNKNOWN_INPUT_ARCH},
'\0', NULL, N_("Accept input files whose architecture cannot be determined"), TWO_DASHES },
{ {"no-accept-unknown-input-arch", no_argument, NULL, OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH},
'\0', NULL, N_("Reject input files whose architecture is unknown"), TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"assert", required_argument, NULL, OPTION_ASSERT},
'\0', N_("KEYWORD"), N_("Ignored for SunOS compatibility"), ONE_DASH },
{ {"Bdynamic", no_argument, NULL, OPTION_CALL_SHARED},
'\0', NULL, N_("Link against shared libraries"), ONE_DASH },
{ {"dy", no_argument, NULL, OPTION_CALL_SHARED},
'\0', NULL, NULL, ONE_DASH },
{ {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
'\0', NULL, NULL, ONE_DASH },
{ {"Bstatic", no_argument, NULL, OPTION_NON_SHARED},
'\0', NULL, N_("Do not link against shared libraries"), ONE_DASH },
{ {"dn", no_argument, NULL, OPTION_NON_SHARED},
'\0', NULL, NULL, ONE_DASH },
{ {"non_shared", no_argument, NULL, OPTION_NON_SHARED},
'\0', NULL, NULL, ONE_DASH },
{ {"static", no_argument, NULL, OPTION_NON_SHARED},
'\0', NULL, NULL, ONE_DASH },
{ {"Bsymbolic", no_argument, NULL, OPTION_SYMBOLIC},
'\0', NULL, N_("Bind global references locally"), ONE_DASH },
{ {"check-sections", no_argument, NULL, OPTION_CHECK_SECTIONS},
'\0', NULL, N_("Check section addresses for overlaps (default)"), TWO_DASHES },
{ {"no-check-sections", no_argument, NULL, OPTION_NO_CHECK_SECTIONS},
'\0', NULL, N_("Do not check section addresses for overlaps"),
TWO_DASHES },
{ {"cref", no_argument, NULL, OPTION_CREF},
'\0', NULL, N_("Output cross reference table"), TWO_DASHES },
{ {"defsym", required_argument, NULL, OPTION_DEFSYM},
'\0', N_("SYMBOL=EXPRESSION"), N_("Define a symbol"), TWO_DASHES },
{ {"demangle", optional_argument, NULL, OPTION_DEMANGLE},
'\0', N_("[=STYLE]"), N_("Demangle symbol names [using STYLE]"), TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"embedded-relocs", no_argument, NULL, OPTION_EMBEDDED_RELOCS},
'\0', NULL, N_("Generate embedded relocs"), TWO_DASHES},
{ {"fini", required_argument, NULL, OPTION_FINI},
'\0', N_("SYMBOL"), N_("Call SYMBOL at unload-time"), ONE_DASH },
1999-05-03 09:29:11 +02:00
{ {"force-exe-suffix", no_argument, NULL, OPTION_FORCE_EXE_SUFFIX},
'\0', NULL, N_("Force generation of file with .exe suffix"), TWO_DASHES},
{ {"gc-sections", no_argument, NULL, OPTION_GC_SECTIONS},
'\0', NULL, N_("Remove unused sections (on some targets)"),
TWO_DASHES },
{ {"no-gc-sections", no_argument, NULL, OPTION_NO_GC_SECTIONS},
'\0', NULL, N_("Don't remove unused sections (default)"),
TWO_DASHES },
{ {"help", no_argument, NULL, OPTION_HELP},
'\0', NULL, N_("Print option help"), TWO_DASHES },
{ {"init", required_argument, NULL, OPTION_INIT},
'\0', N_("SYMBOL"), N_("Call SYMBOL at load-time"), ONE_DASH },
1999-05-03 09:29:11 +02:00
{ {"Map", required_argument, NULL, OPTION_MAP},
'\0', N_("FILE"), N_("Write a map file"), ONE_DASH },
{ {"no-define-common", no_argument, NULL, OPTION_NO_DEFINE_COMMON},
'\0', NULL, N_("Do not define Common storage"), TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"no-demangle", no_argument, NULL, OPTION_NO_DEMANGLE },
'\0', NULL, N_("Do not demangle symbol names"), TWO_DASHES },
{ {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY},
'\0', NULL, N_("Use less memory and more disk I/O"), TWO_DASHES },
{ {"no-undefined", no_argument, NULL, OPTION_NO_UNDEFINED},
2003-08-20 10:37:19 +02:00
'\0', NULL, N_("Do not allow unresolved references in object files"), TWO_DASHES },
{ {"allow-shlib-undefined", no_argument, NULL, OPTION_ALLOW_SHLIB_UNDEFINED},
2003-08-20 10:37:19 +02:00
'\0', NULL, N_("Allow unresolved references in shared libaries"), TWO_DASHES },
{ {"no-allow-shlib-undefined", no_argument, NULL, OPTION_NO_ALLOW_SHLIB_UNDEFINED},
2003-08-20 10:37:19 +02:00
'\0', NULL, N_("Do not allow unresolved references in shared libs"), TWO_DASHES },
{ {"allow-multiple-definition", no_argument, NULL, OPTION_ALLOW_MULTIPLE_DEFINITION},
'\0', NULL, N_("Allow multiple definitions"), TWO_DASHES },
2002-08-08 05:50:18 +02:00
{ {"no-undefined-version", no_argument, NULL, OPTION_NO_UNDEFINED_VERSION},
'\0', NULL, N_("Disallow undefined version"), TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"no-warn-mismatch", no_argument, NULL, OPTION_NO_WARN_MISMATCH},
'\0', NULL, N_("Don't warn about mismatched input files"), TWO_DASHES},
{ {"no-whole-archive", no_argument, NULL, OPTION_NO_WHOLE_ARCHIVE},
'\0', NULL, N_("Turn off --whole-archive"), TWO_DASHES },
{ {"noinhibit-exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
'\0', NULL, N_("Create an output file even if errors occur"), TWO_DASHES },
{ {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
'\0', NULL, NULL, NO_HELP },
{ {"nostdlib", no_argument, NULL, OPTION_NOSTDLIB},
'\0', NULL, N_("Only use library directories specified on\n\t\t\t\tthe command line"), ONE_DASH },
1999-05-03 09:29:11 +02:00
{ {"oformat", required_argument, NULL, OPTION_OFORMAT},
'\0', N_("TARGET"), N_("Specify target of output file"), EXACTLY_TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"qmagic", no_argument, NULL, OPTION_IGNORE},
'\0', NULL, N_("Ignored for Linux compatibility"), ONE_DASH },
{ {"relax", no_argument, NULL, OPTION_RELAX},
'\0', NULL, N_("Relax branches on certain targets"), TWO_DASHES },
{ {"retain-symbols-file", required_argument, NULL,
OPTION_RETAIN_SYMBOLS_FILE},
'\0', N_("FILE"), N_("Keep only symbols listed in FILE"), TWO_DASHES },
{ {"rpath", required_argument, NULL, OPTION_RPATH},
'\0', N_("PATH"), N_("Set runtime shared library search path"), ONE_DASH },
{ {"rpath-link", required_argument, NULL, OPTION_RPATH_LINK},
'\0', N_("PATH"), N_("Set link time shared library search path"), ONE_DASH },
{ {"shared", no_argument, NULL, OPTION_SHARED},
'\0', NULL, N_("Create a shared library"), ONE_DASH },
{ {"Bshareable", no_argument, NULL, OPTION_SHARED }, /* FreeBSD. */
'\0', NULL, NULL, ONE_DASH },
bfd/ * elflink.h (elf_link_add_object_symbols): Use !info->executable instead of info->shared where appropriate. (bfd_elfNN_size_dynamic_sections, elf_link_output_extsym): Likewise. * elflink.c (_bfd_elf_create_got_section): Likewise. (_bfd_elf_link_create_dynamic_sections): Likewise. (_bfd_elf_link_assign_sym_version): Likewise. * elf32-i386.c (elf_i386_size_dynamic_sections): Create .interp section and DT_DEBUG dynamic tag even for position independent executables. * elf32-ppc.c (ppc_elf_size_dynamic_sections): Likewise. * elf32-s390.c (elf_s390_size_dynamic_sections: Likewise. * elf64-ppc.c (ppc64_elf_size_dynamic_sections: Likewise. * elf64-s390.c (elf_s390_size_dynamic_sections: Likewise. * elf64-x86-64.c (elf64_x86_64_size_dynamic_sections: Likewise. * elfxx-ia64.c (elfNN_ia64_size_dynamic_sections: Likewise. * elf32-sparc.c (elf32_sparc_size_dynamic_sections: Likewise. * elf64-alpha.c (elf64_alpha_size_dynamic_sections: Likewise. * elf64-sparc.c (sparc64_elf_size_dynamic_sections: Likewise. include/ * bfdlink.h (struct bfd_link_info): Add pie and executable bits. ld/ * lexsup.c (OPTION_PIE): Define. (ld_options): Add -pie and --pic-executable options. (parse_args): Handle OPTION_PIE. * ldmain.c (main): Initialize link_info.pie and link_info.executable. * genscripts.sh: Generate PIE scripts. * ld.texinfo: Document -pie and --pic-executable options. * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): (gld${EMULATION_NAME}_place_orphan): Likewise. (gld${EMULATION_NAME}_get_script): Include PIE scripts. * scripttempl/elf.sc: In PIE scripts set . the same way as in shared scripts. * emulparams/elf_i386.sh (GENERATE_PIE_SCRIPT): Set to yes. * emulparams/elf64_ia64.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf32ppc.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf64ppc.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf_x86_64.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf_s390.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf32_sparc.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf64_sparc.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf64alpha.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf64_s390.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf_i386.sh (GENERATE_PIE_SCRIPT): Likewise.
2003-05-30 17:50:12 +02:00
{ {"pie", no_argument, NULL, OPTION_PIE},
'\0', NULL, N_("Create a position independent executable"), ONE_DASH },
{ {"pic-executable", no_argument, NULL, OPTION_PIE},
'\0', NULL, NULL, TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"sort-common", no_argument, NULL, OPTION_SORT_COMMON},
'\0', NULL, N_("Sort common symbols by size"), TWO_DASHES },
{ {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
'\0', NULL, NULL, NO_HELP },
* elf-bfd.h (enum elf_reloc_type_class): New. (struct elf_backend_data): Add elf_backend_reloc_type_class. (_bfd_elf_reloc_type_class): New. * elfxx-target.h (elf_backend_reloc_type_class): Define. (elfNN_bed): Add elf_backend_reloc_type_class. * elf.c (_bfd_elf_reloc_type_class): New. * elf32-i386.c (elf_i386_check_relocs): Set DF_TEXTREL if the reloc is against read-only section. (elf_i386_size_dynamic_sections): Use DF_TEXTREL flag instead of looking up section names for DT_TEXTREL. (elf_i386_reloc_type_class): New. (elf_backend_reloc_type_class): Define. * elf32-sparc.c (elf32_sparc_check_relocs): Set DF_TEXTREL if the reloc is against read-only section. (elf32_sparc_size_dynamic_sections): Use DF_TEXTREL flag instead of looking up section names for DT_TEXTREL. (elf32_sparc_reloc_type_class): New. (elf_backend_reloc_type_class): Define. * elf64-sparc.c (sparc64_elf_check_relocs): Set DF_TEXTREL if the reloc is against read-only section. (sparc64_elf_size_dynamic_sections): Use DF_TEXTREL flag instead of looking up section names for DT_TEXTREL. (sparc64_elf_reloc_type_class): New. (elf_backend_reloc_type_class): Define. * elfxx-ia64.c (struct elfNN_ia64_link_hash_table): Add reltext field. (elfNN_ia64_hash_table_create): Clear ia64_info. (get_reloc_section): Set DF_TEXTREL if the reloc is against read-only section. (elfNN_ia64_size_dynamic_sections): Use ia64_info->reltext flag instead of looking up section names for DT_TEXTREL. (elfNN_ia64_reloc_type_class): New. (elf_backend_reloc_type_class): Define. * elflink.h (size_dynamic_sections): Add spare DT_NULL tags. (struct elf_link_sort_rela): New. (elf_link_sort_cmp1, elf_link_sort_cmp2, elf_link_sort_relocs): New. (elf_bfd_final_link): Call elf_link_sort_relocs. Convert one spare DT_NULL into DT_RELCOUNT resp. DT_RELACOUNT if necessary. * bfdlink.h (struct bfd_link_info): Add combreloc and spare_dynamic_tags fields. * emultempl/elf32.em (place_orphan): Place orphan .rel* sections into .rel.dyn resp. .rela.dyn if combreloc. (get_script): If .x linker script is equal to .xn, only put it once into the binary. Add .xc and .xsc scripts. (parse_args): Handle -z combreloc and -z nocombreloc. * scripttempl/elf.sc (.rela.sbss): Fix a typo. For .xc and .xsc scripts put all .rel* or .rela* input sections but .rel*.plt and PLT-like sections into .rel.dyn resp. .rela.dyn. * genscripts.sh (GENERATE_COMBRELOC_SCRIPT): Set if SCRIPT_NAME is elf. Strip trailing whitespace from script. Generate .xc and .xsc scripts if requested. * ldmain.c (main): Initialize link_info.combreloc and link_info.spare_dynamic_tags. * lexsup.c (OPTION_SPARE_DYNAMIC_TAGS): Define. (ld_options): Add --spare-dynamic-tags option. (parse_args): Likewise. * ld.texinfo: Document -z combreloc and -z nocombreloc. * ldint.texinfo: Document .xc and .xsc linker scripts. * NEWS: Add notes about -z combreloc and SHF_MERGE.
2001-08-23 17:14:18 +02:00
{ {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_DYNAMIC_TAGS},
'\0', N_("COUNT"), N_("How many tags to reserve in .dynamic section"), TWO_DASHES },
{ {"split-by-file", optional_argument, NULL, OPTION_SPLIT_BY_FILE},
'\0', N_("[=SIZE]"), N_("Split output sections every SIZE octets"), TWO_DASHES },
{ {"split-by-reloc", optional_argument, NULL, OPTION_SPLIT_BY_RELOC},
'\0', N_("[=COUNT]"), N_("Split output sections every COUNT relocs"), TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"stats", no_argument, NULL, OPTION_STATS},
'\0', NULL, N_("Print memory usage statistics"), TWO_DASHES },
2000-10-17 22:10:20 +02:00
{ {"target-help", no_argument, NULL, OPTION_TARGET_HELP},
'\0', NULL, N_("Display target specific options"), TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"task-link", required_argument, NULL, OPTION_TASK_LINK},
'\0', N_("SYMBOL"), N_("Do task level linking"), TWO_DASHES },
{ {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT},
'\0', NULL, N_("Use same format as native linker"), TWO_DASHES },
{ {"section-start", required_argument, NULL, OPTION_SECTION_START},
'\0', N_("SECTION=ADDRESS"), N_("Set address of named section"), TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"Tbss", required_argument, NULL, OPTION_TBSS},
'\0', N_("ADDRESS"), N_("Set address of .bss section"), ONE_DASH },
{ {"Tdata", required_argument, NULL, OPTION_TDATA},
'\0', N_("ADDRESS"), N_("Set address of .data section"), ONE_DASH },
{ {"Ttext", required_argument, NULL, OPTION_TTEXT},
'\0', N_("ADDRESS"), N_("Set address of .text section"), ONE_DASH },
2003-08-20 10:37:19 +02:00
{ {"unresolved-symbols=<method>", required_argument, NULL, OPTION_UNRESOLVED_SYMBOLS},
'\0', NULL, N_("How to handle unresolved symbols. <method> is:\n\t\t\t\tignore-all, report-all, ignore-in-object-files,\n\t\t\t\tignore-in-shared-libs"),
TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"verbose", no_argument, NULL, OPTION_VERBOSE},
'\0', NULL, N_("Output lots of information during link"), TWO_DASHES },
{ {"dll-verbose", no_argument, NULL, OPTION_VERBOSE}, /* Linux. */
'\0', NULL, NULL, NO_HELP },
{ {"version-script", required_argument, NULL, OPTION_VERSION_SCRIPT },
'\0', N_("FILE"), N_("Read version information script"), TWO_DASHES },
{ {"version-exports-section", required_argument, NULL,
OPTION_VERSION_EXPORTS_SECTION },
1999-05-28 12:50:29 +02:00
'\0', N_("SYMBOL"), N_("Take export symbols list from .exports, using\n\t\t\t\tSYMBOL as the version."),
1999-05-03 09:29:11 +02:00
TWO_DASHES },
{ {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
'\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },
{ {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},
'\0', NULL, N_("Warn if global constructors/destructors are seen"),
TWO_DASHES },
{ {"warn-multiple-gp", no_argument, NULL, OPTION_WARN_MULTIPLE_GP},
'\0', NULL, N_("Warn if the multiple GP values are used"), TWO_DASHES },
{ {"warn-once", no_argument, NULL, OPTION_WARN_ONCE},
'\0', NULL, N_("Warn only once per undefined symbol"), TWO_DASHES },
{ {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN},
'\0', NULL, N_("Warn if start of section changes due to alignment"),
TWO_DASHES },
2003-08-20 10:37:19 +02:00
{ {"warn-unresolved-symbols", no_argument, NULL, OPTION_WARN_UNRESOLVED_SYMBOLS},
'\0', NULL, N_("Report unresolved symbols as warnings"), TWO_DASHES },
{ {"error-unresolved-symbols", no_argument, NULL, OPTION_ERROR_UNRESOLVED_SYMBOLS},
'\0', NULL, N_("Report unresolved symbols as errors"), TWO_DASHES },
{ {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL},
'\0', NULL, N_("Treat warnings as errors"),
TWO_DASHES },
1999-05-03 09:29:11 +02:00
{ {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE},
'\0', NULL, N_("Include all objects from following archives"), TWO_DASHES },
{ {"wrap", required_argument, NULL, OPTION_WRAP},
'\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES },
{ {"mpc860c0", optional_argument, NULL, OPTION_MPC860C0},
1999-05-28 12:50:29 +02:00
'\0', N_("[=WORDS]"), N_("Modify problematic branches in last WORDS (1-10,\n\t\t\t\tdefault 5) words of a page"), TWO_DASHES }
1999-05-03 09:29:11 +02:00
};
#define OPTION_COUNT ARRAY_SIZE (ld_options)
1999-05-03 09:29:11 +02:00
/* Test STRING for containing a string of digits that form a number
between MIN and MAX. The return value is the number or ERR. */
static int
2003-06-28 07:28:54 +02:00
is_num (const char *string, int min, int max, int err)
1999-05-03 09:29:11 +02:00
{
int result = 0;
for (; *string; ++string)
1999-05-03 09:29:11 +02:00
{
if (! ISDIGIT (*string))
{
result = err;
break;
}
result = result * 10 + (*string - '0');
1999-05-03 09:29:11 +02:00
}
if (result < min || result > max)
result = err;
return result;
}
void
2003-06-28 07:28:54 +02:00
parse_args (unsigned argc, char **argv)
1999-05-03 09:29:11 +02:00
{
unsigned i;
int is, il, irl;
1999-05-03 09:29:11 +02:00
int ingroup = 0;
char *default_dirlist = NULL;
* 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-28 02:32:31 +01:00
char *shortopts;
struct option *longopts;
struct option *really_longopts;
1999-05-03 09:29:11 +02:00
int last_optind;
2003-08-20 10:37:19 +02:00
enum report_method how_to_report_unresolved_symbols = RM_GENERATE_ERROR;
1999-05-03 09:29:11 +02:00
2003-06-28 07:28:54 +02:00
shortopts = xmalloc (OPTION_COUNT * 3 + 2);
longopts = xmalloc (sizeof (*longopts) * (OPTION_COUNT + 1));
really_longopts = xmalloc (sizeof (*really_longopts) * (OPTION_COUNT + 1));
* 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-28 02:32:31 +01:00
1999-05-03 09:29:11 +02:00
/* 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
as if it were the argument of an option with character code 1. */
shortopts[0] = '-';
is = 1;
il = 0;
irl = 0;
1999-05-03 09:29:11 +02:00
for (i = 0; i < OPTION_COUNT; i++)
{
if (ld_options[i].shortopt != '\0')
{
shortopts[is] = ld_options[i].shortopt;
++is;
if (ld_options[i].opt.has_arg == required_argument
|| ld_options[i].opt.has_arg == optional_argument)
{
shortopts[is] = ':';
++is;
if (ld_options[i].opt.has_arg == optional_argument)
{
shortopts[is] = ':';
++is;
}
}
}
if (ld_options[i].opt.name != NULL)
{
if (ld_options[i].control == EXACTLY_TWO_DASHES)
{
really_longopts[irl] = ld_options[i].opt;
++irl;
}
else
{
longopts[il] = ld_options[i].opt;
++il;
}
1999-05-03 09:29:11 +02:00
}
}
shortopts[is] = '\0';
longopts[il].name = NULL;
really_longopts[irl].name = NULL;
1999-05-03 09:29:11 +02:00
* 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-28 02:32:31 +01:00
ldemul_add_options (is, &shortopts, il, &longopts, irl, &really_longopts);
1999-05-03 09:29:11 +02:00
/* 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,
the first form takes an argument, while the second does not.
We need to permit the --shared form because on some platforms,
such as Solaris, gcc -shared will pass -G to the linker.
To permit either usage, we look through the argument list. If we
find -G not followed by a number, we change it into --shared.
This will work for most normal cases. */
for (i = 1; i < argc; i++)
if (strcmp (argv[i], "-G") == 0
&& (i + 1 >= argc
|| ! ISDIGIT (argv[i + 1][0])))
1999-05-03 09:29:11 +02:00
argv[i] = (char *) "--shared";
/* Because we permit long options to start with a single dash, and
we have a --library option, and the -l option is conventionally
used with an immediately following argument, we can have bad
results if somebody tries to use -l with a library whose name
happens to start with "ibrary", as in -li. We avoid problems by
simply turning -l into --library. This means that users will
have to use two dashes in order to use --library, which is OK
since that's how it is documented.
FIXME: It's possible that this problem can arise for other short
options as well, although the user does always have the recourse
of adding a space between the option and the argument. */
for (i = 1; i < argc; i++)
{
if (argv[i][0] == '-'
&& argv[i][1] == 'l'
&& argv[i][2] != '\0')
{
char *n;
2003-06-28 07:28:54 +02:00
n = xmalloc (strlen (argv[i]) + 20);
1999-05-03 09:29:11 +02:00
sprintf (n, "--library=%s", argv[i] + 2);
argv[i] = n;
}
}
last_optind = -1;
while (1)
{
int longind;
1999-05-03 09:29:11 +02:00
int optc;
/* Using last_optind lets us avoid calling ldemul_parse_args
multiple times on a single option, which would lead to
confusion in the internal static variables maintained by
getopt. This could otherwise happen for an argument like
-nx, in which the -n is parsed as a single option, and we
loop around to pick up the -x. */
if (optind != last_optind)
if (ldemul_parse_args (argc, argv))
continue;
1999-05-03 09:29:11 +02:00
/* getopt_long_only is like getopt_long, but '-' as well as '--'
can indicate a long option. */
opterr = 0;
last_optind = optind;
1999-05-03 09:29:11 +02:00
optc = getopt_long_only (argc, argv, shortopts, longopts, &longind);
if (optc == '?')
{
optind = last_optind;
optc = getopt_long (argc, argv, "-", really_longopts, &longind);
}
2001-01-13 20:45:52 +01:00
* 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-28 02:32:31 +01:00
if (ldemul_handle_option (optc))
continue;
1999-05-03 09:29:11 +02:00
if (optc == -1)
break;
1999-05-03 09:29:11 +02:00
switch (optc)
{
case '?':
einfo (_("%P: unrecognized option '%s'\n"), argv[last_optind]);
1999-05-03 09:29:11 +02:00
default:
2001-10-31 16:41:19 +01:00
einfo (_("%P%F: use the --help option for usage information\n"));
1999-05-03 09:29:11 +02:00
case 1: /* File name. */
2003-06-28 07:28:54 +02:00
lang_add_input_file (optarg, lang_input_file_is_file_enum, NULL);
1999-05-03 09:29:11 +02:00
break;
case OPTION_IGNORE:
break;
case 'a':
/* For HP/UX compatibility. Actually -a shared should mean
2003-06-28 07:28:54 +02:00
``use only shared libraries'' but, then, we don't
currently support shared libraries on HP/UX anyhow. */
1999-05-03 09:29:11 +02:00
if (strcmp (optarg, "archive") == 0)
config.dynamic_link = FALSE;
1999-05-03 09:29:11 +02:00
else if (strcmp (optarg, "shared") == 0
|| strcmp (optarg, "default") == 0)
config.dynamic_link = TRUE;
1999-05-03 09:29:11 +02:00
else
einfo (_("%P%F: unrecognized -a option `%s'\n"), optarg);
break;
case OPTION_ASSERT:
/* FIXME: We just ignore these, but we should handle them. */
if (strcmp (optarg, "definitions") == 0)
;
else if (strcmp (optarg, "nodefinitions") == 0)
;
else if (strcmp (optarg, "nosymbolic") == 0)
;
else if (strcmp (optarg, "pure-text") == 0)
;
else
einfo (_("%P%F: unrecognized -assert option `%s'\n"), optarg);
break;
case 'A':
ldfile_add_arch (optarg);
break;
case 'b':
lang_add_target (optarg);
break;
case 'c':
ldfile_open_command_file (optarg);
parser_input = input_mri_script;
yyparse ();
break;
case OPTION_CALL_SHARED:
config.dynamic_link = TRUE;
/* When linking against shared libraries, the default behaviour is
to report any unresolved references. Although strictly speaking
it is not a failure to encounter unresolved symbols at link time
- the symbol *might* be available at load time - it is a strong
indication that the resulting executable will not work. Plus it
is necessary for the correct execution of the autoconf package,
which needs to be able to detect functions that are not provided
by the host OS. */
2003-08-20 10:37:19 +02:00
if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
link_info.unresolved_syms_in_objects = how_to_report_unresolved_symbols;
2003-08-20 10:37:19 +02:00
if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
1999-05-03 09:29:11 +02:00
break;
case OPTION_NON_SHARED:
config.dynamic_link = FALSE;
2003-08-20 10:37:19 +02:00
/* When linking against static libraries, the default
behaviour is to report any unresolved references. */
if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
link_info.unresolved_syms_in_objects = how_to_report_unresolved_symbols;
if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
1999-05-03 09:29:11 +02:00
break;
case OPTION_CREF:
command_line.cref = TRUE;
link_info.notice_all = TRUE;
1999-05-03 09:29:11 +02:00
break;
case 'd':
command_line.force_common_definition = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_DEFSYM:
lex_string = optarg;
lex_redirect (optarg);
parser_input = input_defsym;
parsing_defsym = 1;
yyparse ();
parsing_defsym = 0;
lex_string = NULL;
break;
case OPTION_DEMANGLE:
demangling = TRUE;
if (optarg != NULL)
{
enum demangling_styles style;
style = cplus_demangle_name_to_style (optarg);
if (style == unknown_demangling)
einfo (_("%F%P: unknown demangling style `%s'"),
optarg);
cplus_demangle_set_style (style);
}
1999-05-03 09:29:11 +02:00
break;
2001-05-22 16:00:18 +02:00
case 'I': /* Used on Solaris. */
1999-05-03 09:29:11 +02:00
case OPTION_DYNAMIC_LINKER:
command_line.interpreter = optarg;
break;
case OPTION_EB:
command_line.endian = ENDIAN_BIG;
break;
case OPTION_EL:
command_line.endian = ENDIAN_LITTLE;
break;
case OPTION_EMBEDDED_RELOCS:
command_line.embedded_relocs = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_EXPORT_DYNAMIC:
case 'E': /* HP/UX compatibility. */
link_info.export_dynamic = TRUE;
1999-05-03 09:29:11 +02:00
break;
case 'e':
lang_add_entry (optarg, TRUE);
1999-05-03 09:29:11 +02:00
break;
case 'f':
if (command_line.auxiliary_filters == NULL)
{
2003-06-28 07:28:54 +02:00
command_line.auxiliary_filters = xmalloc (2 * sizeof (char *));
1999-05-03 09:29:11 +02:00
command_line.auxiliary_filters[0] = optarg;
command_line.auxiliary_filters[1] = NULL;
}
else
{
int c;
char **p;
c = 0;
for (p = command_line.auxiliary_filters; *p != NULL; p++)
++c;
2003-06-28 07:28:54 +02:00
command_line.auxiliary_filters
= xrealloc (command_line.auxiliary_filters,
(c + 2) * sizeof (char *));
1999-05-03 09:29:11 +02:00
command_line.auxiliary_filters[c] = optarg;
command_line.auxiliary_filters[c + 1] = NULL;
}
break;
case 'F':
command_line.filter_shlib = optarg;
break;
case OPTION_FORCE_EXE_SUFFIX:
command_line.force_exe_suffix = TRUE;
1999-05-03 09:29:11 +02:00
break;
case 'G':
{
char *end;
g_switch_value = strtoul (optarg, &end, 0);
if (*end)
einfo (_("%P%F: invalid number `%s'\n"), optarg);
}
break;
case 'g':
/* Ignore. */
break;
case OPTION_GC_SECTIONS:
command_line.gc_sections = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_HELP:
help ();
xexit (0);
break;
case 'L':
ldfile_add_library_path (optarg, TRUE);
1999-05-03 09:29:11 +02:00
break;
case 'l':
2003-06-28 07:28:54 +02:00
lang_add_input_file (optarg, lang_input_file_is_l_enum, NULL);
1999-05-03 09:29:11 +02:00
break;
case 'M':
config.map_filename = "-";
break;
case 'm':
/* Ignore. Was handled in a pre-parse. */
break;
case OPTION_MAP:
config.map_filename = optarg;
break;
case 'N':
config.text_read_only = FALSE;
config.magic_demand_paged = FALSE;
config.dynamic_link = FALSE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_NO_OMAGIC:
config.text_read_only = TRUE;
config.magic_demand_paged = TRUE;
/* NB/ Does not set dynamic_link to TRUE.
Use --call-shared or -Bdynamic for this. */
break;
1999-05-03 09:29:11 +02:00
case 'n':
config.magic_demand_paged = FALSE;
config.dynamic_link = FALSE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_NO_DEFINE_COMMON:
command_line.inhibit_common_definition = TRUE;
break;
1999-05-03 09:29:11 +02:00
case OPTION_NO_DEMANGLE:
demangling = FALSE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_NO_GC_SECTIONS:
command_line.gc_sections = FALSE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_NO_KEEP_MEMORY:
link_info.keep_memory = FALSE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_NO_UNDEFINED:
2003-08-20 10:37:19 +02:00
link_info.unresolved_syms_in_objects = how_to_report_unresolved_symbols;
1999-05-03 09:29:11 +02:00
break;
case OPTION_ALLOW_SHLIB_UNDEFINED:
2003-08-20 10:37:19 +02:00
link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
break;
case OPTION_NO_ALLOW_SHLIB_UNDEFINED:
2003-08-20 10:37:19 +02:00
link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
break;
2003-08-20 10:37:19 +02:00
case OPTION_UNRESOLVED_SYMBOLS:
if (strcmp (optarg, "ignore-all") == 0)
{
link_info.unresolved_syms_in_objects = RM_IGNORE;
link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
}
else if (strcmp (optarg, "report-all") == 0)
{
link_info.unresolved_syms_in_objects = how_to_report_unresolved_symbols;
link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
}
else if (strcmp (optarg, "ignore-in-object-files") == 0)
{
link_info.unresolved_syms_in_objects = RM_IGNORE;
link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
}
else if (strcmp (optarg, "ignore-in-shared-libs") == 0)
{
link_info.unresolved_syms_in_objects = how_to_report_unresolved_symbols;
link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
}
else
einfo (_("%P%F: bad --unresolved-symbols option: %s\n"), optarg);
break;
case OPTION_WARN_UNRESOLVED_SYMBOLS:
how_to_report_unresolved_symbols = RM_GENERATE_WARNING;
if (link_info.unresolved_syms_in_objects == RM_GENERATE_ERROR)
link_info.unresolved_syms_in_objects = RM_GENERATE_WARNING;
if (link_info.unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)
link_info.unresolved_syms_in_shared_libs = RM_GENERATE_WARNING;
break;
case OPTION_ERROR_UNRESOLVED_SYMBOLS:
how_to_report_unresolved_symbols = RM_GENERATE_ERROR;
if (link_info.unresolved_syms_in_objects == RM_GENERATE_WARNING)
link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
if (link_info.unresolved_syms_in_shared_libs == RM_GENERATE_WARNING)
link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR;
break;
case OPTION_ALLOW_MULTIPLE_DEFINITION:
link_info.allow_multiple_definition = TRUE;
break;
2002-08-08 05:50:18 +02:00
case OPTION_NO_UNDEFINED_VERSION:
link_info.allow_undefined_version = FALSE;
2002-08-08 05:50:18 +02:00
break;
1999-05-03 09:29:11 +02:00
case OPTION_NO_WARN_MISMATCH:
command_line.warn_mismatch = FALSE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_NOINHIBIT_EXEC:
force_make_executable = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_NOSTDLIB:
config.only_cmd_line_lib_dirs = TRUE;
break;
1999-05-03 09:29:11 +02:00
case OPTION_NO_WHOLE_ARCHIVE:
whole_archive = FALSE;
1999-05-03 09:29:11 +02:00
break;
case 'O':
/* FIXME "-O<non-digits> <value>" used to set the address of
section <non-digits>. Was this for compatibility with
something, or can we create a new option to do that
(with a syntax similar to -defsym)?
getopt can't handle two args to an option without kludges. */
/* Enable optimizations of output files. */
link_info.optimize = strtoul (optarg, NULL, 0) ? TRUE : FALSE;
1999-05-03 09:29:11 +02:00
break;
case 'o':
lang_add_output (optarg, 0);
1999-05-03 09:29:11 +02:00
break;
case OPTION_OFORMAT:
2003-06-28 07:28:54 +02:00
lang_add_output_format (optarg, NULL, NULL, 0);
1999-05-03 09:29:11 +02:00
break;
case 'q':
link_info.emitrelocations = TRUE;
break;
case 'i':
1999-05-03 09:29:11 +02:00
case 'r':
2001-10-31 16:41:19 +01:00
if (optind == last_optind)
/* This can happen if the user put "-rpath,a" on the command
line. (Or something similar. The comma is important).
Getopt becomes confused and thinks that this is a -r option
but it cannot parse the text after the -r so it refuses to
increment the optind counter. Detect this case and issue
an error message here. We cannot just make this a warning,
increment optind, and continue because getopt is too confused
and will seg-fault the next time around. */
einfo(_("%P%F: bad -rpath option\n"));
2003-06-25 08:40:27 +02:00
link_info.relocatable = TRUE;
config.build_constructors = FALSE;
config.magic_demand_paged = FALSE;
config.text_read_only = FALSE;
config.dynamic_link = FALSE;
1999-05-03 09:29:11 +02:00
break;
case 'R':
/* The GNU linker traditionally uses -R to mean to include
only the symbols from a file. The Solaris linker uses -R
to set the path used by the runtime linker to find
libraries. This is the GNU linker -rpath argument. We
try to support both simultaneously by checking the file
named. If it is a directory, rather than a regular file,
we assume -rpath was meant. */
{
struct stat s;
if (stat (optarg, &s) >= 0
&& ! S_ISDIR (s.st_mode))
{
lang_add_input_file (optarg,
lang_input_file_is_symbols_only_enum,
2003-06-28 07:28:54 +02:00
NULL);
1999-05-03 09:29:11 +02:00
break;
}
}
/* Fall through. */
case OPTION_RPATH:
if (command_line.rpath == NULL)
command_line.rpath = xstrdup (optarg);
1999-05-03 09:29:11 +02:00
else
{
size_t rpath_len = strlen (command_line.rpath);
size_t optarg_len = strlen (optarg);
char *buf;
char *cp = command_line.rpath;
/* First see whether OPTARG is already in the path. */
do
{
size_t idx = 0;
2001-10-31 16:41:19 +01:00
1999-05-03 09:29:11 +02:00
while (optarg[idx] != '\0' && optarg[idx] == cp[idx])
++idx;
if (optarg[idx] == '\0'
&& (cp[idx] == '\0' || cp[idx] == ':'))
/* We found it. */
break;
/* Not yet found. */
cp = strchr (cp, ':');
if (cp != NULL)
++cp;
}
while (cp != NULL);
if (cp == NULL)
{
buf = xmalloc (rpath_len + optarg_len + 2);
sprintf (buf, "%s:%s", command_line.rpath, optarg);
free (command_line.rpath);
command_line.rpath = buf;
}
}
break;
case OPTION_RPATH_LINK:
if (command_line.rpath_link == NULL)
command_line.rpath_link = xstrdup (optarg);
1999-05-03 09:29:11 +02:00
else
{
char *buf;
buf = xmalloc (strlen (command_line.rpath_link)
+ strlen (optarg)
+ 2);
sprintf (buf, "%s:%s", command_line.rpath_link, optarg);
free (command_line.rpath_link);
command_line.rpath_link = buf;
}
break;
case OPTION_RELAX:
command_line.relax = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_RETAIN_SYMBOLS_FILE:
add_keepsyms_file (optarg);
break;
case 'S':
link_info.strip = strip_debugger;
break;
case 's':
link_info.strip = strip_all;
break;
case OPTION_STRIP_DISCARDED:
link_info.strip_discarded = TRUE;
break;
case OPTION_NO_STRIP_DISCARDED:
link_info.strip_discarded = FALSE;
break;
1999-05-03 09:29:11 +02:00
case OPTION_SHARED:
if (config.has_shared)
2003-08-20 10:37:19 +02:00
{
link_info.shared = TRUE;
/* When creating a shared library, the default
behaviour is to ignore any unresolved references. */
if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
link_info.unresolved_syms_in_objects = RM_IGNORE;
if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
}
1999-05-03 09:29:11 +02:00
else
einfo (_("%P%F: -shared not supported\n"));
break;
bfd/ * elflink.h (elf_link_add_object_symbols): Use !info->executable instead of info->shared where appropriate. (bfd_elfNN_size_dynamic_sections, elf_link_output_extsym): Likewise. * elflink.c (_bfd_elf_create_got_section): Likewise. (_bfd_elf_link_create_dynamic_sections): Likewise. (_bfd_elf_link_assign_sym_version): Likewise. * elf32-i386.c (elf_i386_size_dynamic_sections): Create .interp section and DT_DEBUG dynamic tag even for position independent executables. * elf32-ppc.c (ppc_elf_size_dynamic_sections): Likewise. * elf32-s390.c (elf_s390_size_dynamic_sections: Likewise. * elf64-ppc.c (ppc64_elf_size_dynamic_sections: Likewise. * elf64-s390.c (elf_s390_size_dynamic_sections: Likewise. * elf64-x86-64.c (elf64_x86_64_size_dynamic_sections: Likewise. * elfxx-ia64.c (elfNN_ia64_size_dynamic_sections: Likewise. * elf32-sparc.c (elf32_sparc_size_dynamic_sections: Likewise. * elf64-alpha.c (elf64_alpha_size_dynamic_sections: Likewise. * elf64-sparc.c (sparc64_elf_size_dynamic_sections: Likewise. include/ * bfdlink.h (struct bfd_link_info): Add pie and executable bits. ld/ * lexsup.c (OPTION_PIE): Define. (ld_options): Add -pie and --pic-executable options. (parse_args): Handle OPTION_PIE. * ldmain.c (main): Initialize link_info.pie and link_info.executable. * genscripts.sh: Generate PIE scripts. * ld.texinfo: Document -pie and --pic-executable options. * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): (gld${EMULATION_NAME}_place_orphan): Likewise. (gld${EMULATION_NAME}_get_script): Include PIE scripts. * scripttempl/elf.sc: In PIE scripts set . the same way as in shared scripts. * emulparams/elf_i386.sh (GENERATE_PIE_SCRIPT): Set to yes. * emulparams/elf64_ia64.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf32ppc.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf64ppc.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf_x86_64.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf_s390.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf32_sparc.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf64_sparc.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf64alpha.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf64_s390.sh (GENERATE_PIE_SCRIPT): Likewise. * emulparams/elf_i386.sh (GENERATE_PIE_SCRIPT): Likewise.
2003-05-30 17:50:12 +02:00
case OPTION_PIE:
if (config.has_shared)
{
link_info.shared = TRUE;
link_info.pie = TRUE;
}
else
einfo (_("%P%F: -pie not supported\n"));
break;
1999-05-03 09:29:11 +02:00
case 'h': /* Used on Solaris. */
case OPTION_SONAME:
command_line.soname = optarg;
break;
case OPTION_SORT_COMMON:
config.sort_common = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_STATS:
config.stats = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_SYMBOLIC:
link_info.symbolic = TRUE;
1999-05-03 09:29:11 +02:00
break;
case 't':
trace_files = TRUE;
1999-05-03 09:29:11 +02:00
break;
case 'T':
ldfile_open_command_file (optarg);
parser_input = input_script;
yyparse ();
break;
case OPTION_SECTION_START:
{
char *optarg2;
2000-07-08 15:35:05 +02:00
char *sec_name;
int len;
/* Check for <something>=<somthing>... */
optarg2 = strchr (optarg, '=');
if (optarg2 == NULL)
2001-10-31 16:41:19 +01:00
einfo (_("%P%F: invalid argument to option \"--section-start\"\n"));
optarg2++;
/* So far so good. Are all the args present? */
if ((*optarg == '\0') || (*optarg2 == '\0'))
2001-10-31 16:41:19 +01:00
einfo (_("%P%F: missing argument(s) to option \"--section-start\"\n"));
2000-07-08 15:35:05 +02:00
/* We must copy the section name as set_section_start
doesn't do it for us. */
len = optarg2 - optarg;
sec_name = xmalloc (len);
memcpy (sec_name, optarg, len - 1);
sec_name[len - 1] = 0;
/* Then set it... */
2000-07-08 15:35:05 +02:00
set_section_start (sec_name, optarg2);
}
break;
2000-10-17 22:10:20 +02:00
case OPTION_TARGET_HELP:
/* Mention any target specific options. */
ldemul_list_emulation_options (stdout);
exit (0);
1999-05-03 09:29:11 +02:00
case OPTION_TBSS:
set_section_start (".bss", optarg);
break;
case OPTION_TDATA:
set_section_start (".data", optarg);
break;
case OPTION_TTEXT:
set_section_start (".text", optarg);
break;
case OPTION_TRADITIONAL_FORMAT:
link_info.traditional_format = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_TASK_LINK:
link_info.task_link = TRUE;
1999-05-03 09:29:11 +02:00
/* Fall through - do an implied -r option. */
case OPTION_UR:
2003-06-25 08:40:27 +02:00
link_info.relocatable = TRUE;
config.build_constructors = TRUE;
config.magic_demand_paged = FALSE;
config.text_read_only = FALSE;
config.dynamic_link = FALSE;
1999-05-03 09:29:11 +02:00
break;
case 'u':
ldlang_add_undef (optarg);
break;
case OPTION_UNIQUE:
2001-01-14 05:36:35 +01:00
if (optarg != NULL)
lang_add_unique (optarg);
else
config.unique_orphan_sections = TRUE;
break;
1999-05-03 09:29:11 +02:00
case OPTION_VERBOSE:
ldversion (1);
version_printed = TRUE;
trace_file_tries = TRUE;
overflow_cutoff_limit = -2;
1999-05-03 09:29:11 +02:00
break;
case 'v':
ldversion (0);
version_printed = TRUE;
1999-05-03 09:29:11 +02:00
break;
case 'V':
ldversion (1);
version_printed = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_VERSION:
ldversion (2);
1999-05-03 09:29:11 +02:00
xexit (0);
break;
case OPTION_VERSION_SCRIPT:
/* This option indicates a small script that only specifies
2003-06-28 07:28:54 +02:00
version information. Read it, but don't assume that
we've seen a linker script. */
1999-05-03 09:29:11 +02:00
{
FILE *hold_script_handle;
1999-05-03 09:29:11 +02:00
hold_script_handle = saved_script_handle;
1999-05-03 09:29:11 +02:00
ldfile_open_command_file (optarg);
saved_script_handle = hold_script_handle;
1999-05-03 09:29:11 +02:00
parser_input = input_version_script;
yyparse ();
}
break;
case OPTION_VERSION_EXPORTS_SECTION:
/* This option records a version symbol to be applied to the
symbols listed for export to be found in the object files
.exports sections. */
command_line.version_exports_section = optarg;
break;
case OPTION_WARN_COMMON:
config.warn_common = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_WARN_CONSTRUCTORS:
config.warn_constructors = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_WARN_FATAL:
config.fatal_warnings = TRUE;
break;
1999-05-03 09:29:11 +02:00
case OPTION_WARN_MULTIPLE_GP:
config.warn_multiple_gp = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_WARN_ONCE:
config.warn_once = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_WARN_SECTION_ALIGN:
config.warn_section_align = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_WHOLE_ARCHIVE:
whole_archive = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_WRAP:
add_wrap (optarg);
break;
bfd/ * libbfd-in.h (_bfd_merge_section): New. (_bfd_write_merged_section): New. (_bfd_merged_section_offset): New. * libbfd.h: Rebuilt. * linker.c (_bfd_generic_link_output_symbols): Handle discard_sec_merge. * aoutx.h (aout_link_write_symbols): Likewise. * pdp11.c (aout_link_write_symbols): Likewise. * elflink.h (elf_link_add_object_symbols): Call _bfd_merge_section. (elf_bfd_final_link): Adjust global symbols pointing into SEC_MERGE sections. (elf_link_sec_merge_syms): New. (elf_link_input_bfd): Call _bfd_merged_section_offset and _bfd_write_merged_section. Handle discard_sec_merge. * elf-bfd.h (struct elf_link_hash_table): Add merge_info field. (struct bfd_elf_section_data): Likewise. * elf.c (_bfd_elf_make_section_from_shdr): Set SEC_MERGE and SEC_STRINGS section flags and entsize from their ELF counterparts. (_bfd_elf_link_hash_table_init): Initialize merge_info. (elf_fake_sections): Set SHF_MERGE, SHF_STRINGS and sh_entsize from their BFD counterparts. * merge.c: New file. * Makefile.am: Add strtab.lo. * Makefile.in: Rebuilt. include/ * bfdlink.h (bfd_link_discard): Add discard_sec_merge. gas/ * config/obj-elf.c (obj_elf_change_section): Add entsize argument, handle SHF_MERGE and SHF_STRINGS. (obj_elf_parse_section_letters): Set SHF_MERGE and SHF_STRINGS. (obj_elf_section): Allow additional argument specifying entity size. * write.c (adjust_reloc_syms): Keep relocations against local symbols in SEC_MERGE sections. ld/ * ldmain.c (main): Default to discard_sec_merge. * lexsup.c (OPTION_DISCARD_NONE): Define. (ld_options): Add --discard-none. (parse_args): Handle OPTION_DISCARD_NONE. * ldlang.c (wild_doit): SEC_MERGE should be set in the output section only if SEC_MERGE and SEC_STRINGS flags and entsize of all its input sections match.
2001-04-13 02:34:36 +02:00
case OPTION_DISCARD_NONE:
link_info.discard = discard_none;
break;
1999-05-03 09:29:11 +02:00
case 'X':
link_info.discard = discard_l;
break;
case 'x':
link_info.discard = discard_all;
break;
case 'Y':
if (strncmp (optarg, "P,", 2) == 0)
optarg += 2;
2003-03-31 20:13:25 +02:00
if (default_dirlist != NULL)
free (default_dirlist);
1999-05-03 09:29:11 +02:00
default_dirlist = xstrdup (optarg);
break;
case 'y':
add_ysym (optarg);
break;
* elf-bfd.h (enum elf_reloc_type_class): New. (struct elf_backend_data): Add elf_backend_reloc_type_class. (_bfd_elf_reloc_type_class): New. * elfxx-target.h (elf_backend_reloc_type_class): Define. (elfNN_bed): Add elf_backend_reloc_type_class. * elf.c (_bfd_elf_reloc_type_class): New. * elf32-i386.c (elf_i386_check_relocs): Set DF_TEXTREL if the reloc is against read-only section. (elf_i386_size_dynamic_sections): Use DF_TEXTREL flag instead of looking up section names for DT_TEXTREL. (elf_i386_reloc_type_class): New. (elf_backend_reloc_type_class): Define. * elf32-sparc.c (elf32_sparc_check_relocs): Set DF_TEXTREL if the reloc is against read-only section. (elf32_sparc_size_dynamic_sections): Use DF_TEXTREL flag instead of looking up section names for DT_TEXTREL. (elf32_sparc_reloc_type_class): New. (elf_backend_reloc_type_class): Define. * elf64-sparc.c (sparc64_elf_check_relocs): Set DF_TEXTREL if the reloc is against read-only section. (sparc64_elf_size_dynamic_sections): Use DF_TEXTREL flag instead of looking up section names for DT_TEXTREL. (sparc64_elf_reloc_type_class): New. (elf_backend_reloc_type_class): Define. * elfxx-ia64.c (struct elfNN_ia64_link_hash_table): Add reltext field. (elfNN_ia64_hash_table_create): Clear ia64_info. (get_reloc_section): Set DF_TEXTREL if the reloc is against read-only section. (elfNN_ia64_size_dynamic_sections): Use ia64_info->reltext flag instead of looking up section names for DT_TEXTREL. (elfNN_ia64_reloc_type_class): New. (elf_backend_reloc_type_class): Define. * elflink.h (size_dynamic_sections): Add spare DT_NULL tags. (struct elf_link_sort_rela): New. (elf_link_sort_cmp1, elf_link_sort_cmp2, elf_link_sort_relocs): New. (elf_bfd_final_link): Call elf_link_sort_relocs. Convert one spare DT_NULL into DT_RELCOUNT resp. DT_RELACOUNT if necessary. * bfdlink.h (struct bfd_link_info): Add combreloc and spare_dynamic_tags fields. * emultempl/elf32.em (place_orphan): Place orphan .rel* sections into .rel.dyn resp. .rela.dyn if combreloc. (get_script): If .x linker script is equal to .xn, only put it once into the binary. Add .xc and .xsc scripts. (parse_args): Handle -z combreloc and -z nocombreloc. * scripttempl/elf.sc (.rela.sbss): Fix a typo. For .xc and .xsc scripts put all .rel* or .rela* input sections but .rel*.plt and PLT-like sections into .rel.dyn resp. .rela.dyn. * genscripts.sh (GENERATE_COMBRELOC_SCRIPT): Set if SCRIPT_NAME is elf. Strip trailing whitespace from script. Generate .xc and .xsc scripts if requested. * ldmain.c (main): Initialize link_info.combreloc and link_info.spare_dynamic_tags. * lexsup.c (OPTION_SPARE_DYNAMIC_TAGS): Define. (ld_options): Add --spare-dynamic-tags option. (parse_args): Likewise. * ld.texinfo: Document -z combreloc and -z nocombreloc. * ldint.texinfo: Document .xc and .xsc linker scripts. * NEWS: Add notes about -z combreloc and SHF_MERGE.
2001-08-23 17:14:18 +02:00
case OPTION_SPARE_DYNAMIC_TAGS:
link_info.spare_dynamic_tags = strtoul (optarg, NULL, 0);
break;
1999-05-03 09:29:11 +02:00
case OPTION_SPLIT_BY_RELOC:
if (optarg != NULL)
config.split_by_reloc = strtoul (optarg, NULL, 0);
else
config.split_by_reloc = 32768;
break;
1999-05-03 09:29:11 +02:00
case OPTION_SPLIT_BY_FILE:
if (optarg != NULL)
config.split_by_file = bfd_scan_vma (optarg, NULL, 0);
else
config.split_by_file = 1;
break;
1999-05-03 09:29:11 +02:00
case OPTION_CHECK_SECTIONS:
command_line.check_section_addresses = TRUE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_NO_CHECK_SECTIONS:
command_line.check_section_addresses = FALSE;
1999-05-03 09:29:11 +02:00
break;
case OPTION_ACCEPT_UNKNOWN_INPUT_ARCH:
command_line.accept_unknown_input_arch = TRUE;
break;
case OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH:
command_line.accept_unknown_input_arch = FALSE;
break;
1999-05-03 09:29:11 +02:00
case '(':
if (ingroup)
2001-10-31 16:41:19 +01:00
einfo (_("%P%F: may not nest groups (--help for usage)\n"));
1999-05-03 09:29:11 +02:00
lang_enter_group ();
ingroup = 1;
break;
case ')':
if (! ingroup)
2001-10-31 16:41:19 +01:00
einfo (_("%P%F: group ended before it began (--help for usage)\n"));
1999-05-03 09:29:11 +02:00
lang_leave_group ();
ingroup = 0;
break;
case OPTION_MPC860C0:
2001-10-31 16:41:19 +01:00
/* Default value (in bytes). */
link_info.mpc860c0 = 20;
if (optarg)
{
unsigned words;
1999-05-03 09:29:11 +02:00
words = is_num (optarg, 1, 10, 0);
if (words == 0)
2001-10-31 16:41:19 +01:00
einfo (_("%P%F: invalid argument to option \"mpc860c0\"\n"));
/* Convert words to bytes. */
link_info.mpc860c0 = words * 4;
}
command_line.relax = TRUE;
break;
case OPTION_INIT:
link_info.init_function = optarg;
break;
case OPTION_FINI:
link_info.fini_function = optarg;
break;
1999-05-03 09:29:11 +02:00
}
}
if (ingroup)
lang_leave_group ();
if (default_dirlist != NULL)
2003-03-31 20:13:25 +02:00
{
set_default_dirlist (default_dirlist);
free (default_dirlist);
}
2003-08-20 10:37:19 +02:00
if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
/* FIXME: Should we allow emulations a chance to set this ? */
link_info.unresolved_syms_in_objects = how_to_report_unresolved_symbols;
if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
/* FIXME: Should we allow emulations a chance to set this ? */
link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
1999-05-03 09:29:11 +02:00
}
/* Add the (colon-separated) elements of DIRLIST_PTR to the
library search path. */
static void
2003-06-28 07:28:54 +02:00
set_default_dirlist (char *dirlist_ptr)
1999-05-03 09:29:11 +02:00
{
char *p;
while (1)
{
p = strchr (dirlist_ptr, PATH_SEPARATOR);
if (p != NULL)
*p = '\0';
if (*dirlist_ptr != '\0')
ldfile_add_library_path (dirlist_ptr, TRUE);
1999-05-03 09:29:11 +02:00
if (p == NULL)
break;
dirlist_ptr = p + 1;
}
}
static void
2003-06-28 07:28:54 +02:00
set_section_start (char *sect, char *valstr)
1999-05-03 09:29:11 +02:00
{
const char *end;
bfd_vma val = bfd_scan_vma (valstr, &end, 16);
1999-05-03 09:29:11 +02:00
if (*end)
einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
lang_section_start (sect, exp_intop (val));
}
/* Print help messages for the options. */
static void
2003-06-28 07:28:54 +02:00
help (void)
1999-05-03 09:29:11 +02:00
{
unsigned i;
1999-05-03 09:29:11 +02:00
const char **targets, **pp;
printf (_("Usage: %s [options] file...\n"), program_name);
printf (_("Options:\n"));
for (i = 0; i < OPTION_COUNT; i++)
{
if (ld_options[i].doc != NULL)
{
bfd_boolean comma;
1999-05-03 09:29:11 +02:00
int len;
unsigned j;
1999-05-03 09:29:11 +02:00
printf (" ");
comma = FALSE;
1999-05-03 09:29:11 +02:00
len = 2;
j = i;
do
{
if (ld_options[j].shortopt != '\0'
&& ld_options[j].control != NO_HELP)
{
printf ("%s-%c", comma ? ", " : "", ld_options[j].shortopt);
len += (comma ? 2 : 0) + 2;
if (ld_options[j].arg != NULL)
{
if (ld_options[j].opt.has_arg != optional_argument)
{
printf (" ");
++len;
}
printf ("%s", _(ld_options[j].arg));
len += strlen (_(ld_options[j].arg));
}
comma = TRUE;
1999-05-03 09:29:11 +02:00
}
++j;
}
while (j < OPTION_COUNT && ld_options[j].doc == NULL);
j = i;
do
{
if (ld_options[j].opt.name != NULL
&& ld_options[j].control != NO_HELP)
{
int two_dashes =
(ld_options[j].control == TWO_DASHES
|| ld_options[j].control == EXACTLY_TWO_DASHES);
1999-05-03 09:29:11 +02:00
printf ("%s-%s%s",
comma ? ", " : "",
two_dashes ? "-" : "",
1999-05-03 09:29:11 +02:00
ld_options[j].opt.name);
len += ((comma ? 2 : 0)
+ 1
+ (two_dashes ? 1 : 0)
1999-05-03 09:29:11 +02:00
+ strlen (ld_options[j].opt.name));
if (ld_options[j].arg != NULL)
{
printf (" %s", _(ld_options[j].arg));
len += 1 + strlen (_(ld_options[j].arg));
}
comma = TRUE;
1999-05-03 09:29:11 +02:00
}
++j;
}
while (j < OPTION_COUNT && ld_options[j].doc == NULL);
if (len >= 30)
{
printf ("\n");
len = 0;
}
for (; len < 30; len++)
putchar (' ');
printf ("%s\n", _(ld_options[i].doc));
}
}
/* Note: Various tools (such as libtool) depend upon the
format of the listings below - do not change them. */
1999-05-03 09:29:11 +02:00
/* xgettext:c-format */
printf (_("%s: supported targets:"), program_name);
1999-05-03 09:29:11 +02:00
targets = bfd_target_list ();
for (pp = targets; *pp != NULL; pp++)
printf (" %s", *pp);
free (targets);
printf ("\n");
/* xgettext:c-format */
printf (_("%s: supported emulations: "), program_name);
1999-05-03 09:29:11 +02:00
ldemul_list_emulations (stdout);
printf ("\n");
/* xgettext:c-format */
printf (_("%s: emulation specific options:\n"), program_name);
ldemul_list_emulation_options (stdout);
printf ("\n");
2000-04-03 16:10:05 +02:00
printf (_("Report bugs to %s\n"), REPORT_BUGS_TO);
1999-05-03 09:29:11 +02:00
}