/* Parse options for the GNU linker.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
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. */
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+#include "config.h"
#include "bfd.h"
#include "sysdep.h"
#include "libiberty.h"
static void set_default_dirlist (char *);
static void set_section_start (char *, char *);
+static void set_segment_start (const char *, char *);
static void help (void);
/* Non-zero if we are processing a --defsym from the command line. */
OPTION_DEFSYM,
OPTION_DEMANGLE,
OPTION_DYNAMIC_LINKER,
+ OPTION_SYSROOT,
OPTION_EB,
OPTION_EL,
OPTION_EMBEDDED_RELOCS,
OPTION_SHARED,
OPTION_SONAME,
OPTION_SORT_COMMON,
+ OPTION_SORT_SECTION,
OPTION_STATS,
OPTION_SYMBOLIC,
+ OPTION_SYMBOLIC_FUNCTIONS,
OPTION_TASK_LINK,
OPTION_TBSS,
OPTION_TDATA,
OPTION_VERSION,
OPTION_VERSION_SCRIPT,
OPTION_VERSION_EXPORTS_SECTION,
+ OPTION_DYNAMIC_LIST,
+ OPTION_DYNAMIC_LIST_CPP_NEW,
+ OPTION_DYNAMIC_LIST_CPP_TYPEINFO,
+ OPTION_DYNAMIC_LIST_DATA,
OPTION_WARN_COMMON,
OPTION_WARN_CONSTRUCTORS,
OPTION_WARN_FATAL,
OPTION_FORCE_EXE_SUFFIX,
OPTION_GC_SECTIONS,
OPTION_NO_GC_SECTIONS,
+ OPTION_PRINT_GC_SECTIONS,
+ OPTION_NO_PRINT_GC_SECTIONS,
OPTION_HASH_SIZE,
OPTION_CHECK_SECTIONS,
OPTION_NO_CHECK_SECTIONS,
OPTION_NO_ALLOW_SHLIB_UNDEFINED,
OPTION_ALLOW_MULTIPLE_DEFINITION,
OPTION_NO_UNDEFINED_VERSION,
+ OPTION_DEFAULT_SYMVER,
+ OPTION_DEFAULT_IMPORTED_SYMVER,
OPTION_DISCARD_NONE,
OPTION_SPARE_DYNAMIC_TAGS,
OPTION_NO_DEFINE_COMMON,
OPTION_UNRESOLVED_SYMBOLS,
OPTION_WARN_UNRESOLVED_SYMBOLS,
OPTION_ERROR_UNRESOLVED_SYMBOLS,
- OPTION_REDUCE_MEMORY_OVERHEADS
+ OPTION_WARN_SHARED_TEXTREL,
+ OPTION_REDUCE_MEMORY_OVERHEADS,
+ OPTION_DEFAULT_SCRIPT
};
/* The long options. This structure is used for both the option
{ {"library-path", required_argument, NULL, 'L'},
'L', N_("DIRECTORY"), N_("Add DIRECTORY to library search path"),
TWO_DASHES },
+ { {"sysroot=<DIRECTORY>", required_argument, NULL, OPTION_SYSROOT},
+ '\0', NULL, N_("Override the default sysroot location"), TWO_DASHES },
{ {NULL, required_argument, NULL, '\0'},
'm', N_("EMULATION"), N_("Set emulation"), ONE_DASH },
{ {"print-map", no_argument, NULL, 'M'},
't', NULL, N_("Trace file opens"), TWO_DASHES },
{ {"script", required_argument, NULL, 'T'},
'T', N_("FILE"), N_("Read linker script"), TWO_DASHES },
+ { {"default-script", required_argument, NULL, OPTION_DEFAULT_SCRIPT},
+ '\0', N_("FILE"), N_("Read default linker script"), TWO_DASHES },
+ { {"dT", required_argument, NULL, OPTION_DEFAULT_SCRIPT},
+ '\0', NULL, NULL, ONE_DASH },
{ {"undefined", required_argument, NULL, 'u'},
'u', N_("SYMBOL"), N_("Start with undefined reference to SYMBOL"),
TWO_DASHES },
OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH},
'\0', NULL, N_("Reject input files whose architecture is unknown"),
TWO_DASHES },
+ { {"add-needed", no_argument, NULL, OPTION_ADD_NEEDED},
+ '\0', NULL, N_("Set DT_NEEDED tags for DT_NEEDED entries in\n"
+ "\t\t\t\tfollowing dynamic libs"), TWO_DASHES },
+ { {"no-add-needed", no_argument, NULL, OPTION_NO_ADD_NEEDED},
+ '\0', NULL, N_("Do not set DT_NEEDED tags for DT_NEEDED entries\n"
+ "\t\t\t\tin following dynamic libs"), TWO_DASHES },
+ { {"as-needed", no_argument, NULL, OPTION_AS_NEEDED},
+ '\0', NULL, N_("Only set DT_NEEDED for following dynamic libs if used"),
+ TWO_DASHES },
+ { {"no-as-needed", no_argument, NULL, OPTION_NO_AS_NEEDED},
+ '\0', NULL, N_("Always set DT_NEEDED for following dynamic libs"),
+ TWO_DASHES },
{ {"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, NULL, ONE_DASH },
{ {"Bsymbolic", no_argument, NULL, OPTION_SYMBOLIC},
'\0', NULL, N_("Bind global references locally"), ONE_DASH },
+ { {"Bsymbolic-functions", no_argument, NULL, OPTION_SYMBOLIC_FUNCTIONS},
+ '\0', NULL, N_("Bind global function references locally"), ONE_DASH },
{ {"check-sections", no_argument, NULL, OPTION_CHECK_SECTIONS},
'\0', NULL, N_("Check section addresses for overlaps (default)"),
TWO_DASHES },
TWO_DASHES },
{ {"embedded-relocs", no_argument, NULL, OPTION_EMBEDDED_RELOCS},
'\0', NULL, N_("Generate embedded relocs"), TWO_DASHES},
+ { {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL},
+ '\0', NULL, N_("Treat warnings as errors"),
+ TWO_DASHES },
{ {"fini", required_argument, NULL, OPTION_FINI},
'\0', N_("SYMBOL"), N_("Call SYMBOL at unload-time"), ONE_DASH },
{ {"force-exe-suffix", no_argument, NULL, OPTION_FORCE_EXE_SUFFIX},
{ {"no-gc-sections", no_argument, NULL, OPTION_NO_GC_SECTIONS},
'\0', NULL, N_("Don't remove unused sections (default)"),
TWO_DASHES },
+ { {"print-gc-sections", no_argument, NULL, OPTION_PRINT_GC_SECTIONS},
+ '\0', NULL, N_("List removed unused sections on stderr"),
+ TWO_DASHES },
+ { {"no-print-gc-sections", no_argument, NULL, OPTION_NO_PRINT_GC_SECTIONS},
+ '\0', NULL, N_("Do not list removed unused sections"),
+ TWO_DASHES },
{ {"hash-size=<NUMBER>", required_argument, NULL, OPTION_HASH_SIZE},
'\0', NULL, N_("Set default hash table size close to <NUMBER>"),
TWO_DASHES },
'\0', NULL, N_("Allow multiple definitions"), TWO_DASHES },
{ {"no-undefined-version", no_argument, NULL, OPTION_NO_UNDEFINED_VERSION},
'\0', NULL, N_("Disallow undefined version"), TWO_DASHES },
+ { {"default-symver", no_argument, NULL, OPTION_DEFAULT_SYMVER},
+ '\0', NULL, N_("Create default symbol version"), TWO_DASHES },
+ { {"default-imported-symver", no_argument, NULL,
+ OPTION_DEFAULT_IMPORTED_SYMVER},
+ '\0', NULL, N_("Create default symbol version for imported symbols"),
+ TWO_DASHES },
{ {"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_("Sort common symbols by size"), TWO_DASHES },
{ {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
'\0', NULL, NULL, NO_HELP },
+ { {"sort-section", required_argument, NULL, OPTION_SORT_SECTION},
+ '\0', N_("name|alignment"),
+ N_("Sort sections by name or maximum alignment"), TWO_DASHES },
{ {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_DYNAMIC_TAGS},
'\0', N_("COUNT"), N_("How many tags to reserve in .dynamic section"),
TWO_DASHES },
OPTION_VERSION_EXPORTS_SECTION },
'\0', N_("SYMBOL"), N_("Take export symbols list from .exports, using\n"
"\t\t\t\tSYMBOL as the version."), TWO_DASHES },
+ { {"dynamic-list-data", no_argument, NULL, OPTION_DYNAMIC_LIST_DATA},
+ '\0', NULL, N_("Add data symbols to dynamic list"), TWO_DASHES },
+ { {"dynamic-list-cpp-new", no_argument, NULL, OPTION_DYNAMIC_LIST_CPP_NEW},
+ '\0', NULL, N_("Use C++ operator new/delete dynamic list"), TWO_DASHES },
+ { {"dynamic-list-cpp-typeinfo", no_argument, NULL, OPTION_DYNAMIC_LIST_CPP_TYPEINFO},
+ '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },
+ { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},
+ '\0', N_("FILE"), N_("Read dynamic list"), 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},
{ {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN},
'\0', NULL, N_("Warn if start of section changes due to alignment"),
TWO_DASHES },
+ { {"warn-shared-textrel", no_argument, NULL, OPTION_WARN_SHARED_TEXTREL},
+ '\0', NULL, N_("Warn if shared object has DT_TEXTREL"),
+ TWO_DASHES },
{ {"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 },
{ {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE},
'\0', NULL, N_("Include all objects from following archives"),
TWO_DASHES },
- { {"add-needed", no_argument, NULL, OPTION_ADD_NEEDED},
- '\0', NULL, N_("Set DT_NEEDED tags for DT_NEEDED entries in\n"
- "\t\t\t\tfollowing dynamic libs"), TWO_DASHES },
- { {"no-add-needed", no_argument, NULL, OPTION_NO_ADD_NEEDED},
- '\0', NULL, N_("Do not set DT_NEEDED tags for DT_NEEDED entries\n"
- "\t\t\t\tin following dynamic libs"), TWO_DASHES },
- { {"as-needed", no_argument, NULL, OPTION_AS_NEEDED},
- '\0', NULL, N_("Only set DT_NEEDED for following dynamic libs if used"),
- TWO_DASHES },
- { {"no-as-needed", no_argument, NULL, OPTION_NO_AS_NEEDED},
- '\0', NULL, N_("Always set DT_NEEDED for following dynamic libs"),
- TWO_DASHES },
{ {"wrap", required_argument, NULL, OPTION_WRAP},
'\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES },
};
{
case '?':
einfo (_("%P: unrecognized option '%s'\n"), argv[last_optind]);
+ /* Fall through. */
+
default:
einfo (_("%P%F: use the --help option for usage information\n"));
case OPTION_DYNAMIC_LINKER:
command_line.interpreter = optarg;
break;
+ case OPTION_SYSROOT:
+ /* Already handled in ldmain.c. */
+ break;
case OPTION_EB:
command_line.endian = ENDIAN_BIG;
break;
/* Ignore. */
break;
case OPTION_GC_SECTIONS:
- command_line.gc_sections = TRUE;
+ link_info.gc_sections = TRUE;
+ break;
+ case OPTION_PRINT_GC_SECTIONS:
+ link_info.print_gc_sections = TRUE;
break;
case OPTION_HELP:
help ();
demangling = FALSE;
break;
case OPTION_NO_GC_SECTIONS:
- command_line.gc_sections = FALSE;
+ link_info.gc_sections = FALSE;
+ break;
+ case OPTION_NO_PRINT_GC_SECTIONS:
+ link_info.print_gc_sections = FALSE;
break;
case OPTION_NO_KEEP_MEMORY:
link_info.keep_memory = FALSE;
case OPTION_NO_UNDEFINED_VERSION:
link_info.allow_undefined_version = FALSE;
break;
+ case OPTION_DEFAULT_SYMVER:
+ link_info.create_default_symver = TRUE;
+ break;
+ case OPTION_DEFAULT_IMPORTED_SYMVER:
+ link_info.default_imported_symver = TRUE;
+ break;
case OPTION_NO_WARN_MISMATCH:
command_line.warn_mismatch = FALSE;
break;
case OPTION_SORT_COMMON:
config.sort_common = TRUE;
break;
+ case OPTION_SORT_SECTION:
+ if (strcmp (optarg, N_("name")) == 0)
+ sort_section = by_name;
+ else if (strcmp (optarg, N_("alignment")) == 0)
+ sort_section = by_alignment;
+ else
+ einfo (_("%P%F: invalid section sorting option: %s\n"),
+ optarg);
+ break;
case OPTION_STATS:
config.stats = TRUE;
break;
case OPTION_SYMBOLIC:
- link_info.symbolic = TRUE;
+ command_line.symbolic = symbolic;
+ break;
+ case OPTION_SYMBOLIC_FUNCTIONS:
+ command_line.symbolic = symbolic_functions;
break;
case 't':
trace_files = TRUE;
parser_input = input_script;
yyparse ();
break;
+ case OPTION_DEFAULT_SCRIPT:
+ command_line.default_script = optarg;
+ break;
case OPTION_SECTION_START:
{
char *optarg2;
ldemul_list_emulation_options (stdout);
exit (0);
case OPTION_TBSS:
- set_section_start (".bss", optarg);
+ set_segment_start (".bss", optarg);
break;
case OPTION_TDATA:
- set_section_start (".data", optarg);
+ set_segment_start (".data", optarg);
break;
case OPTION_TTEXT:
- set_section_start (".text", optarg);
+ set_segment_start (".text", optarg);
break;
case OPTION_TRADITIONAL_FORMAT:
link_info.traditional_format = TRUE;
.exports sections. */
command_line.version_exports_section = optarg;
break;
+ case OPTION_DYNAMIC_LIST_DATA:
+ command_line.dynamic_list = dynamic_list_data;
+ if (command_line.symbolic == symbolic)
+ command_line.symbolic = symbolic_unset;
+ break;
+ case OPTION_DYNAMIC_LIST_CPP_TYPEINFO:
+ lang_append_dynamic_list_cpp_typeinfo ();
+ if (command_line.dynamic_list != dynamic_list_data)
+ command_line.dynamic_list = dynamic_list;
+ if (command_line.symbolic == symbolic)
+ command_line.symbolic = symbolic_unset;
+ break;
+ case OPTION_DYNAMIC_LIST_CPP_NEW:
+ lang_append_dynamic_list_cpp_new ();
+ if (command_line.dynamic_list != dynamic_list_data)
+ command_line.dynamic_list = dynamic_list;
+ if (command_line.symbolic == symbolic)
+ command_line.symbolic = symbolic_unset;
+ break;
+ case OPTION_DYNAMIC_LIST:
+ /* This option indicates a small script that only specifies
+ a dynamic list. Read it, but don't assume that we've
+ seen a linker script. */
+ {
+ FILE *hold_script_handle;
+
+ hold_script_handle = saved_script_handle;
+ ldfile_open_command_file (optarg);
+ saved_script_handle = hold_script_handle;
+ parser_input = input_dynamic_list;
+ yyparse ();
+ }
+ if (command_line.dynamic_list != dynamic_list_data)
+ command_line.dynamic_list = dynamic_list;
+ if (command_line.symbolic == symbolic)
+ command_line.symbolic = symbolic_unset;
+ break;
case OPTION_WARN_COMMON:
config.warn_common = TRUE;
break;
case OPTION_WARN_SECTION_ALIGN:
config.warn_section_align = TRUE;
break;
+ case OPTION_WARN_SHARED_TEXTREL:
+ link_info.warn_shared_textrel = TRUE;
+ break;
case OPTION_WHOLE_ARCHIVE:
whole_archive = TRUE;
break;
link_info.discard = discard_all;
break;
case 'Y':
- if (strncmp (optarg, "P,", 2) == 0)
+ if (CONST_STRNEQ (optarg, "P,"))
optarg += 2;
if (default_dirlist != NULL)
free (default_dirlist);
break;
case OPTION_REDUCE_MEMORY_OVERHEADS:
- command_line.reduce_memory_overheads = TRUE;
+ link_info.reduce_memory_overheads = TRUE;
if (config.hash_table_size == 0)
config.hash_table_size = 1021;
break;
bfd_vma val = bfd_scan_vma (valstr, &end, 16);
if (*end)
einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
- lang_section_start (sect, exp_intop (val));
+ lang_section_start (sect, exp_intop (val), NULL);
+}
+
+static void
+set_segment_start (const char *section, char *valstr)
+{
+ const char *name;
+ const char *end;
+ segment_type *seg;
+
+ bfd_vma val = bfd_scan_vma (valstr, &end, 16);
+ if (*end)
+ einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
+ /* If we already have an entry for this segment, update the existing
+ value. */
+ name = section + 1;
+ for (seg = segments; seg; seg = seg->next)
+ if (strcmp (seg->name, name) == 0)
+ {
+ seg->value = val;
+ return;
+ }
+ /* There was no existing value so we must create a new segment
+ entry. */
+ seg = stat_alloc (sizeof (*seg));
+ seg->name = name;
+ seg->value = val;
+ seg->used = FALSE;
+ /* Add it to the linked list of segments. */
+ seg->next = segments;
+ segments = seg;
+ /* Historically, -Ttext and friends set the base address of a
+ particular section. For backwards compatibility, we still do
+ that. If a SEGMENT_START directive is seen, the section address
+ assignment will be disabled. */
+ lang_section_start (section, exp_intop (val), seg);
}
+
\f
/* Print help messages for the options. */
{
unsigned i;
const char **targets, **pp;
+ int len;
printf (_("Usage: %s [options] file...\n"), program_name);
if (ld_options[i].doc != NULL)
{
bfd_boolean comma;
- int len;
unsigned j;
printf (" ");
printf ("%s\n", _(ld_options[i].doc));
}
}
+ printf (_(" @FILE"));
+ for (len = strlen (" @FILE"); len < 30; len++)
+ putchar (' ');
+ printf (_("Read options from FILE\n"));
/* Note: Various tools (such as libtool) depend upon the
format of the listings below - do not change them. */
ldemul_list_emulation_options (stdout);
printf ("\n");
- printf (_("Report bugs to %s\n"), REPORT_BUGS_TO);
+ if (REPORT_BUGS_TO[0])
+ printf (_("Report bugs to %s\n"), REPORT_BUGS_TO);
}