diff options
Diffstat (limited to 'contrib/binutils/ld/ldmain.c')
-rw-r--r-- | contrib/binutils/ld/ldmain.c | 229 |
1 files changed, 150 insertions, 79 deletions
diff --git a/contrib/binutils/ld/ldmain.c b/contrib/binutils/ld/ldmain.c index d0e0b12..fbc3081 100644 --- a/contrib/binutils/ld/ldmain.c +++ b/contrib/binutils/ld/ldmain.c @@ -1,6 +1,6 @@ /* Main program of GNU linker. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004 + 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Written by Steve Chamberlain steve@cygnus.com @@ -18,8 +18,8 @@ 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 "bfd.h" #include "sysdep.h" @@ -50,7 +50,7 @@ #include <string.h> #ifdef HAVE_SBRK -#ifdef NEED_DECLARATION_SBRK +#if !HAVE_DECL_SBRK extern void *sbrk (); #endif #endif @@ -68,7 +68,7 @@ const char *output_filename = "a.out"; char *program_name; /* The prefix for system library directories. */ -char *ld_sysroot; +const char *ld_sysroot; /* The canonical representation of ld_sysroot. */ char * ld_canon_sysroot; @@ -97,6 +97,10 @@ bfd_boolean whole_archive; actually satisfies some reference in a regular object. */ bfd_boolean as_needed; +/* Nonzero means never create DT_NEEDED entries for dynamic libraries + in DT_NEEDED tags. */ +bfd_boolean add_needed = TRUE; + /* TRUE if we should demangle symbol names. */ bfd_boolean demangling; @@ -104,6 +108,10 @@ args_type command_line; ld_config_type config; +sort_type sort_section; + +static const char *get_sysroot + (int, char **); static char *get_emulation (int, char **); static void set_scripts_dir @@ -131,8 +139,8 @@ static bfd_boolean undefined_symbol (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma, bfd_boolean); static bfd_boolean reloc_overflow - (struct bfd_link_info *, const char *, const char *, bfd_vma, - bfd *, asection *, bfd_vma); + (struct bfd_link_info *, struct bfd_link_hash_entry *, const char *, + const char *, bfd_vma, bfd *, asection *, bfd_vma); static bfd_boolean reloc_dangerous (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma); static bfd_boolean unattached_reloc @@ -153,7 +161,7 @@ static struct bfd_link_callbacks link_callbacks = reloc_dangerous, unattached_reloc, notice, - error_handler + einfo }; struct bfd_link_info link_info; @@ -166,7 +174,7 @@ remove_output (void) if (output_bfd) bfd_cache_close (output_bfd); if (delete_output_file_on_failure) - unlink (output_filename); + unlink_if_ordinary (output_filename); } } @@ -190,53 +198,26 @@ main (int argc, char **argv) START_PROGRESS (program_name, 0); + expandargv (&argc, &argv); + bfd_init (); bfd_set_error_program_name (program_name); xatexit (remove_output); -#ifdef TARGET_SYSTEM_ROOT_RELOCATABLE - ld_sysroot = make_relative_prefix (program_name, BINDIR, - TARGET_SYSTEM_ROOT); - - if (ld_sysroot) + /* Set up the sysroot directory. */ + ld_sysroot = get_sysroot (argc, argv); + if (*ld_sysroot) { - struct stat s; - int res = stat (ld_sysroot, &s) == 0 && S_ISDIR (s.st_mode); - - if (!res) + if (*TARGET_SYSTEM_ROOT == 0) { - free (ld_sysroot); - ld_sysroot = NULL; - } - } - - if (! ld_sysroot) - { - ld_sysroot = make_relative_prefix (program_name, TOOLBINDIR, - TARGET_SYSTEM_ROOT); - - if (ld_sysroot) - { - struct stat s; - int res = stat (ld_sysroot, &s) == 0 && S_ISDIR (s.st_mode); - - if (!res) - { - free (ld_sysroot); - ld_sysroot = NULL; - } + einfo ("%P%F: this linker was not configured to use sysroots\n"); + ld_sysroot = ""; } + else + ld_canon_sysroot = lrealpath (ld_sysroot); } - - if (! ld_sysroot) -#endif - ld_sysroot = TARGET_SYSTEM_ROOT; - - if (ld_sysroot && *ld_sysroot) - ld_canon_sysroot = lrealpath (ld_sysroot); - if (ld_canon_sysroot) ld_canon_sysroot_len = strlen (ld_canon_sysroot); else @@ -267,6 +248,7 @@ main (int argc, char **argv) config.has_shared = FALSE; config.split_by_reloc = (unsigned) -1; config.split_by_file = (bfd_size_type) -1; + config.hash_table_size = 0; command_line.force_common_definition = FALSE; command_line.inhibit_common_definition = FALSE; command_line.interpreter = NULL; @@ -274,6 +256,9 @@ main (int argc, char **argv) command_line.warn_mismatch = TRUE; command_line.check_section_addresses = TRUE; command_line.accept_unknown_input_arch = FALSE; + command_line.reduce_memory_overheads = FALSE; + + sort_section = none; /* We initialize DEMANGLING based on the environment variable COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the @@ -297,12 +282,15 @@ main (int argc, char **argv) link_info.unresolved_syms_in_shared_libs = RM_NOT_YET_SET; link_info.allow_multiple_definition = FALSE; link_info.allow_undefined_version = TRUE; + link_info.create_default_symver = FALSE; + link_info.default_imported_symver = FALSE; link_info.keep_memory = TRUE; link_info.notice_all = FALSE; link_info.nocopyreloc = FALSE; link_info.new_dtags = FALSE; link_info.combreloc = TRUE; link_info.eh_frame_hdr = FALSE; + link_info.relro = FALSE; link_info.strip_discarded = TRUE; link_info.strip = strip_none; link_info.discard = discard_sec_merge; @@ -325,7 +313,9 @@ main (int argc, char **argv) link_info.spare_dynamic_tags = 5; link_info.flags = 0; link_info.flags_1 = 0; - link_info.need_relax_finalize = FALSE; + link_info.relax_pass = 1; + link_info.warn_shared_textrel = FALSE; + link_info.gc_sections = FALSE; ldfile_add_arch (""); @@ -342,11 +332,14 @@ main (int argc, char **argv) lang_has_input_file = FALSE; parse_args (argc, argv); + if (config.hash_table_size != 0) + bfd_hash_set_default_size (config.hash_table_size); + ldemul_set_symbols (); if (link_info.relocatable) { - if (command_line.gc_sections) + if (link_info.gc_sections) einfo ("%P%F: --gc-sections and -r may not be used together\n"); else if (command_line.relax) einfo (_("%P%F: --relax and -r may not be used together\n")); @@ -481,6 +474,8 @@ main (int argc, char **argv) if (nocrossref_list != NULL) check_nocrossrefs (); + lang_finish (); + /* Even if we're producing relocatable output, some non-fatal errors should be reported in the exit status. (What non-fatal errors, if any, do we want to ignore for relocatable output?) */ @@ -568,6 +563,51 @@ main (int argc, char **argv) return 0; } +/* If the configured sysroot is relocatable, try relocating it based on + default prefix FROM. Return the relocated directory if it exists, + otherwise return null. */ + +static char * +get_relative_sysroot (const char *from ATTRIBUTE_UNUSED) +{ +#ifdef TARGET_SYSTEM_ROOT_RELOCATABLE + char *path; + struct stat s; + + path = make_relative_prefix (program_name, from, TARGET_SYSTEM_ROOT); + if (path) + { + if (stat (path, &s) == 0 && S_ISDIR (s.st_mode)) + return path; + free (path); + } +#endif + return 0; +} + +/* Return the sysroot directory. Return "" if no sysroot is being used. */ + +static const char * +get_sysroot (int argc, char **argv) +{ + int i; + const char *path; + + for (i = 1; i < argc; i++) + if (strncmp (argv[i], "--sysroot=", strlen ("--sysroot=")) == 0) + return argv[i] + strlen ("--sysroot="); + + path = get_relative_sysroot (BINDIR); + if (path) + return path; + + path = get_relative_sysroot (TOOLBINDIR); + if (path) + return path; + + return TARGET_SYSTEM_ROOT; +} + /* We need to find any explicitly given emulation in order to initialize the state that's needed by the lex&yacc argument parser (parse_args). */ @@ -737,9 +777,10 @@ add_ysym (const char *name) if (link_info.notice_hash == NULL) { link_info.notice_hash = xmalloc (sizeof (struct bfd_hash_table)); - if (! bfd_hash_table_init_n (link_info.notice_hash, - bfd_hash_newfunc, - 61)) + if (!bfd_hash_table_init_n (link_info.notice_hash, + bfd_hash_newfunc, + sizeof (struct bfd_hash_entry), + 61)) einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); } @@ -755,9 +796,10 @@ add_wrap (const char *name) if (link_info.wrap_hash == NULL) { link_info.wrap_hash = xmalloc (sizeof (struct bfd_hash_table)); - if (! bfd_hash_table_init_n (link_info.wrap_hash, - bfd_hash_newfunc, - 61)) + if (!bfd_hash_table_init_n (link_info.wrap_hash, + bfd_hash_newfunc, + sizeof (struct bfd_hash_entry), + 61)) einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); } @@ -787,7 +829,8 @@ add_keepsyms_file (const char *filename) } link_info.keep_hash = xmalloc (sizeof (struct bfd_hash_table)); - if (! bfd_hash_table_init (link_info.keep_hash, bfd_hash_newfunc)) + if (!bfd_hash_table_init (link_info.keep_hash, bfd_hash_newfunc, + sizeof (struct bfd_hash_entry))) einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); bufsize = 100; @@ -835,7 +878,7 @@ add_keepsyms_file (const char *filename) a link. */ static bfd_boolean -add_archive_element (struct bfd_link_info *info ATTRIBUTE_UNUSED, +add_archive_element (struct bfd_link_info *info, bfd *abfd, const char *name) { @@ -866,7 +909,7 @@ add_archive_element (struct bfd_link_info *info ATTRIBUTE_UNUSED, bfd *from; int len; - h = bfd_link_hash_lookup (link_info.hash, name, FALSE, FALSE, TRUE); + h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE); if (h == NULL) from = NULL; @@ -1107,7 +1150,7 @@ constructor_callback (struct bfd_link_info *info, /* Ensure that BFD_RELOC_CTOR exists now, so that we can give a useful error message. */ if (bfd_reloc_type_lookup (output_bfd, BFD_RELOC_CTOR) == NULL - && (link_info.relocatable + && (info->relocatable || bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL)) einfo (_("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n")); @@ -1163,11 +1206,11 @@ warning_callback (struct bfd_link_info *info ATTRIBUTE_UNUSED, return TRUE; if (section != NULL) - einfo ("%C: %s\n", abfd, section, address, warning); + einfo ("%C: %s%s\n", abfd, section, address, _("warning: "), warning); else if (abfd == NULL) - einfo ("%P: %s\n", warning); + einfo ("%P: %s%s\n", _("warning: "), warning); else if (symbol == NULL) - einfo ("%B: %s\n", abfd, warning); + einfo ("%B: %s%s\n", abfd, _("warning: "), warning); else { lang_input_statement_type *entry; @@ -1205,7 +1248,7 @@ warning_callback (struct bfd_link_info *info ATTRIBUTE_UNUSED, bfd_map_over_sections (abfd, warning_find_reloc, &info); if (! info.found) - einfo ("%B: %s\n", abfd, warning); + einfo ("%B: %s%s\n", abfd, _("warning: "), warning); if (entry == NULL) free (asymbols); @@ -1253,7 +1296,8 @@ warning_find_reloc (bfd *abfd, asection *sec, void *iarg) && strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), info->symbol) == 0) { /* We found a reloc for the symbol we are looking for. */ - einfo ("%C: %s\n", abfd, sec, q->address, info->warning); + einfo ("%C: %s%s\n", abfd, sec, q->address, _("warning: "), + info->warning); info->found = TRUE; break; } @@ -1285,7 +1329,8 @@ undefined_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED, if (hash == NULL) { hash = xmalloc (sizeof (struct bfd_hash_table)); - if (! bfd_hash_table_init (hash, bfd_hash_newfunc)) + if (!bfd_hash_table_init (hash, bfd_hash_newfunc, + sizeof (struct bfd_hash_entry))) einfo (_("%F%P: bfd_hash_table_init failed: %E\n")); } @@ -1372,6 +1417,7 @@ int overflow_cutoff_limit = 10; static bfd_boolean reloc_overflow (struct bfd_link_info *info ATTRIBUTE_UNUSED, + struct bfd_link_hash_entry *entry, const char *name, const char *reloc_name, bfd_vma addend, @@ -1382,10 +1428,7 @@ reloc_overflow (struct bfd_link_info *info ATTRIBUTE_UNUSED, if (overflow_cutoff_limit == -1) return TRUE; - if (abfd == NULL) - einfo (_("%P%X: generated")); - else - einfo ("%X%C:", abfd, section, address); + einfo ("%X%C:", abfd, section, address); if (overflow_cutoff_limit >= 0 && overflow_cutoff_limit-- == 0) @@ -1394,7 +1437,34 @@ reloc_overflow (struct bfd_link_info *info ATTRIBUTE_UNUSED, return TRUE; } - einfo (_(" relocation truncated to fit: %s %T"), reloc_name, name); + if (entry) + { + while (entry->type == bfd_link_hash_indirect + || entry->type == bfd_link_hash_warning) + entry = entry->u.i.link; + switch (entry->type) + { + case bfd_link_hash_undefined: + case bfd_link_hash_undefweak: + einfo (_(" relocation truncated to fit: %s against undefined symbol `%T'"), + reloc_name, entry->root.string); + break; + case bfd_link_hash_defined: + case bfd_link_hash_defweak: + einfo (_(" relocation truncated to fit: %s against symbol `%T' defined in %A section in %B"), + reloc_name, entry->root.string, + entry->u.def.section, + entry->u.def.section == bfd_abs_section_ptr + ? output_bfd : entry->u.def.section->owner); + break; + default: + abort (); + break; + } + } + else + einfo (_(" relocation truncated to fit: %s against `%T'"), + reloc_name, name); if (addend != 0) einfo ("+%v", addend); einfo ("\n"); @@ -1410,11 +1480,8 @@ reloc_dangerous (struct bfd_link_info *info ATTRIBUTE_UNUSED, asection *section, bfd_vma address) { - if (abfd == NULL) - einfo (_("%P%X: generated")); - else - einfo ("%X%C:", abfd, section, address); - einfo (_("dangerous relocation: %s\n"), message); + einfo (_("%X%C: dangerous relocation: %s\n"), + abfd, section, address, message); return TRUE; } @@ -1428,11 +1495,8 @@ unattached_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED, asection *section, bfd_vma address) { - if (abfd == NULL) - einfo (_("%P%X: generated")); - else - einfo ("%X%C:", abfd, section, address); - einfo (_(" reloc refers to symbol `%T' which is not being output\n"), name); + einfo (_("%X%C: reloc refers to symbol `%T' which is not being output\n"), + abfd, section, address, name); return TRUE; } @@ -1447,6 +1511,13 @@ notice (struct bfd_link_info *info, asection *section, bfd_vma value) { + if (name == NULL) + { + if (command_line.cref || nocrossref_list != NULL) + return handle_asneeded_cref (abfd, value); + return TRUE; + } + if (! info->notice_all || (info->notice_hash != NULL && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL)) |