/* Main program of GNU linker.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004
+ 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Written by Steve Chamberlain steve@cygnus.com
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"
#include <string.h>
#ifdef HAVE_SBRK
-#ifdef NEED_DECLARATION_SBRK
+#if !HAVE_DECL_SBRK
extern void *sbrk ();
#endif
#endif
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;
sort_type sort_section;
+static const char *get_sysroot
+ (int, char **);
static char *get_emulation
(int, char **);
static void set_scripts_dir
reloc_overflow,
reloc_dangerous,
unattached_reloc,
- notice
+ notice,
+ einfo
};
struct bfd_link_info link_info;
if (output_bfd)
bfd_cache_close (output_bfd);
if (delete_output_file_on_failure)
- unlink (output_filename);
+ unlink_if_ordinary (output_filename);
}
}
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
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.flags_1 = 0;
link_info.need_relax_finalize = FALSE;
link_info.warn_shared_textrel = FALSE;
+ link_info.gc_sections = FALSE;
ldfile_add_arch ("");
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"));
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?) */
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). */
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)
{
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;
/* 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"));
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;
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);
&& 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;
}
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)
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->owner);
+ entry->u.def.section,
+ entry->u.def.section == bfd_abs_section_ptr
+ ? output_bfd : entry->u.def.section->owner);
break;
default:
abort ();
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;
}
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;
}