/* Linker command language support.
- Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001
Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
fill_type, bfd_vma, boolean));
static void lang_finish PARAMS ((void));
static void ignore_bfd_errors PARAMS ((const char *, ...));
+static void record_bfd_errors PARAMS ((const char *, ...));
static void lang_check PARAMS ((void));
static void lang_common PARAMS ((void));
static boolean lang_one_common PARAMS ((struct bfd_link_hash_entry *, PTR));
lang_memory_region_type *new =
(lang_memory_region_type *) stat_alloc (sizeof (lang_memory_region_type));
- new->name = buystring (name);
+ new->name = xstrdup (name);
new->next = (lang_memory_region_type *) NULL;
*lang_memory_region_list_tail = new;
if (! first && (section->output_section->flags & SEC_READONLY) == 0)
flags &= ~ SEC_READONLY;
+ /* Keep SEC_MERGE and SEC_STRINGS only if they are the same. */
+ if (! first
+ && ((section->output_section->flags & (SEC_MERGE | SEC_STRINGS))
+ != (flags & (SEC_MERGE | SEC_STRINGS))
+ || ((flags & SEC_MERGE)
+ && section->output_section->entsize != section->entsize)))
+ {
+ section->output_section->flags &= ~ (SEC_MERGE | SEC_STRINGS);
+ flags &= ~ (SEC_MERGE | SEC_STRINGS);
+ }
+
section->output_section->flags |= flags;
+ if (flags & SEC_MERGE)
+ section->output_section->entsize = section->entsize;
+
/* If SEC_READONLY is not set in the input section, then clear
it from the output section. */
if ((section->flags & SEC_READONLY) == 0)
lang_statement_list_type *hold;
err = bfd_get_error ();
+
+ /* See if the emulation has some special knowledge. */
+ if (ldemul_unrecognized_file (entry))
+ return;
+
if (err == bfd_error_file_ambiguously_recognized)
{
char **p;
bfd_close (entry->the_bfd);
entry->the_bfd = NULL;
- /* See if the emulation has some special knowledge. */
-
- if (ldemul_unrecognized_file (entry))
- return;
-
/* Try to interpret the file as a linker script. */
-
ldfile_open_command_file (entry->filename);
hold = stat_ptr;
if (s->input_statement.real)
{
lang_statement_list_type add;
+ bfd_error_handler_type pfn;
s->input_statement.target = current_target;
bfd_archive))
s->input_statement.loaded = false;
- lang_list_init (&add);
+ lang_list_init (& add);
+
+ /* We need to know if an error occurs whilst loading the
+ symbols, since this means that a valid executable can
+ not be produced. */
+ pfn = bfd_set_error_handler (record_bfd_errors);
load_symbols (&s->input_statement, &add);
+ bfd_set_error_handler (pfn);
+
if (add.head != NULL)
{
*add.tail = s->next;
new->next = ldlang_undef_chain_list_head;
ldlang_undef_chain_list_head = new;
- new->name = buystring (name);
+ new->name = xstrdup (name);
}
/* Run through the list of undefineds created above and place them
#define IGNORE_SECTION(bfd, s) \
(((bfd_get_section_flags (bfd, s) & (SEC_ALLOC | SEC_LOAD)) != (SEC_ALLOC | SEC_LOAD)) \
|| bfd_section_size (bfd, s) == 0)
-
/* Check to see if any allocated sections overlap with other allocated
sections. This can happen when the linker script specifically specifies
the output section addresses of the two sections. */
asection *s;
unsigned opb = bfd_octets_per_byte (output_bfd);
+
/* Scan all sections in the output list. */
for (s = output_bfd->sections; s != NULL; s = s->next)
{
}
}
+
+/* This is the routine to handle BFD error messages. */
+
+#ifdef ANSI_PROTOTYPES
+
+static void
+record_bfd_errors (const char *s, ...)
+{
+ va_list p;
+
+ einfo ("%P: ");
+
+ va_start (p, s);
+
+ vfprintf (stderr, s, p);
+
+ va_end (p);
+
+ fprintf (stderr, "\n");
+
+ einfo ("%X");
+}
+
+#else /* ! defined (ANSI_PROTOTYPES) */
+
+static void
+record_bfd_errors (va_alist)
+ va_dcl
+{
+ va_list p;
+ const char *s;
+
+ einfo ("%P: ");
+
+ va_start (p);
+
+ s = va_arg (p, const char *);
+ vfprintf (stderr, s, p);
+
+ va_end (p);
+
+ fprintf (stderr, "\n");
+
+ einfo ("%X");
+}
+
+#endif /* ! defined (ANSI_PROTOTYPES) */
/* This is a small function used when we want to ignore errors from
BFD. */
l->os->region = region;
/* We only set lma_region for the first overlay section, as
subsequent overlay sections will have load_base set relative
- to the first section. */
- if (lma_region != NULL && l->os->lma_region == NULL && l->next == NULL)
+ to the first section. Also, don't set lma_region if
+ load_base is specified. FIXME: There should really be a test
+ that `AT ( LDADDR )' doesn't conflict with `AT >LMA_REGION'
+ rather than letting LDADDR simply override LMA_REGION. */
+ if (lma_region != NULL && l->os->lma_region == NULL
+ && l->next == NULL && l->os->load_base == NULL)
l->os->lma_region = lma_region;
if (phdrs != NULL && l->os->phdrs == NULL)
l->os->phdrs = phdrs;