Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#include "libiberty.h"
#include "safe-ctype.h"
#include "obstack.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
static const char *startup_file;
-static lang_statement_list_type input_file_chain;
static bfd_boolean placed_commons = FALSE;
static bfd_boolean stripped_excluded_sections = FALSE;
static lang_output_section_statement_type *default_common_section;
lang_statement_list_type lang_output_section_statement;
lang_statement_list_type *stat_ptr = &statement_list;
lang_statement_list_type file_chain = { NULL, NULL };
+lang_statement_list_type input_file_chain;
struct bfd_sym_chain entry_symbol = { NULL, NULL };
static const char *entry_symbol_default = "start";
const char *entry_section = ".text";
lang_has_input_file = TRUE;
p->target = target;
p->sysrooted = FALSE;
+
+ if (file_type == lang_input_file_is_l_enum
+ && name[0] == ':' && name[1] != '\0')
+ {
+ file_type = lang_input_file_is_search_file_enum;
+ name = name + 1;
+ }
+
switch (file_type)
{
case lang_input_file_is_symbols_only_enum:
lang_input_file_enum_type file_type,
const char *target)
{
- lang_has_input_file = TRUE;
return new_afile (name, file_type, target, TRUE);
}
e_align = exp_unop (ALIGN_K,
exp_intop ((bfd_vma) 1 << s->alignment_power));
lang_add_assignment (exp_assop ('=', ".", e_align));
- lang_add_assignment (exp_assop ('=', symname,
- exp_nameop (NAME, ".")));
+ lang_add_assignment (exp_provide (symname,
+ exp_nameop (NAME, "."),
+ FALSE));
}
}
symname = (char *) xmalloc (ps - secname + sizeof "__stop_" + 1);
symname[0] = bfd_get_symbol_leading_char (output_bfd);
sprintf (symname + (symname[0] != 0), "__stop_%s", secname);
- lang_add_assignment (exp_assop ('=', symname,
- exp_nameop (NAME, ".")));
+ lang_add_assignment (exp_provide (symname,
+ exp_nameop (NAME, "."),
+ FALSE));
}
/* Restore the global list pointer. */
switch (output->sectype)
{
case normal_section:
+ case overlay_section:
break;
case noalloc_section:
flags &= ~SEC_ALLOC;
}
else
{
- /* If the current vma overlaps the previous section,
- then set the current lma to that at the end of
- the previous section. The previous section was
- probably an overlay. */
- if ((dot >= last->vma
- && dot < last->vma + last->size)
- || (last->vma >= dot
- && last->vma < dot + os->bfd_section->size))
+ /* If this is an overlay, set the current lma to that
+ at the end of the previous section. */
+ if (os->sectype == overlay_section)
lma = last->lma + last->size;
/* Otherwise, keep the same lma to vma relationship
return dot;
}
-/* Callback routine that is used in _bfd_elf_map_sections_to_segments. */
+/* Callback routine that is used in _bfd_elf_map_sections_to_segments.
+ The BFD library has set NEW_SEGMENT to TRUE iff it thinks that
+ CURRENT_SECTION and PREVIOUS_SECTION ought to be placed into different
+ segments. We are allowed an opportunity to override this decision. */
bfd_boolean
ldlang_override_segment_assignment (struct bfd_link_info * info ATTRIBUTE_UNUSED,
{
lang_output_section_statement_type * cur;
lang_output_section_statement_type * prev;
-
+
+ /* The checks below are only necessary when the BFD library has decided
+ that the two sections ought to be placed into the same segment. */
if (new_segment)
return TRUE;
/* Find the memory regions associated with the two sections.
We call lang_output_section_find() here rather than scanning the list
of output sections looking for a matching section pointer because if
- we have a large number of sections a hash lookup is faster. */
+ we have a large number of sections then a hash lookup is faster. */
cur = lang_output_section_find (current_section->name);
prev = lang_output_section_find (previous_section->name);
+ /* More paranoia. */
if (cur == NULL || prev == NULL)
return new_segment;
/* If the regions are different then force the sections to live in
- different segments. See the email thread starting here for the
- reasons why this is necessary:
+ different segments. See the email thread starting at the following
+ URL for the reasons why this is necessary:
http://sourceware.org/ml/binutils/2007-02/msg00216.html */
return cur->region != prev->region;
}
if (compatible == NULL)
{
if (command_line.warn_mismatch)
- einfo (_("%P: warning: %s architecture of input file `%B'"
+ einfo (_("%P%X: %s architecture of input file `%B'"
" is incompatible with %s output\n"),
bfd_printable_name (input_bfd), input_bfd,
bfd_printable_name (output_bfd));
header_printed = TRUE;
}
- name = demangle (h->root.string);
- minfo ("%s", name);
- len = strlen (name);
- free (name);
+ name = bfd_demangle (output_bfd, h->root.string,
+ DMGL_ANSI | DMGL_PARAMS);
+ if (name == NULL)
+ {
+ minfo ("%s", h->root.string);
+ len = strlen (h->root.string);
+ }
+ else
+ {
+ minfo ("%s", name);
+ len = strlen (name);
+ free (name);
+ }
if (len >= 19)
{
void
ldlang_add_file (lang_input_statement_type *entry)
{
- bfd **pp;
-
lang_statement_append (&file_chain,
(lang_statement_union_type *) entry,
&entry->next);
a link. */
ASSERT (entry->the_bfd->link_next == NULL);
ASSERT (entry->the_bfd != output_bfd);
- for (pp = &link_info.input_bfds; *pp != NULL; pp = &(*pp)->link_next)
- ;
- *pp = entry->the_bfd;
+
+ *link_info.input_bfds_tail = entry->the_bfd;
+ link_info.input_bfds_tail = &entry->the_bfd->link_next;
entry->the_bfd->usrdata = entry;
bfd_set_gp_size (entry->the_bfd, g_switch_value);
/* Keep relaxing until bfd_relax_section gives up. */
bfd_boolean relax_again;
+ link_info.relax_trip = -1;
do
{
relax_again = FALSE;
+ link_info.relax_trip++;
/* Note: pe-dll.c does something like this also. If you find
you need to change this code, you probably need to change
alc = 10;
secs = xmalloc (alc * sizeof (asection *));
last = NULL;
+
for (l = lang_phdr_list; l != NULL; l = l->next)
{
unsigned int c;
|| os->bfd_section == NULL
|| (os->bfd_section->flags & SEC_ALLOC) == 0)
continue;
- pl = last;
+
+ if (last)
+ pl = last;
+ else
+ {
+ lang_output_section_statement_type * tmp_os;
+
+ /* If we have not run across a section with a program
+ header assigned to it yet, then scan forwards to find
+ one. This prevents inconsistencies in the linker's
+ behaviour when a script has specified just a single
+ header and there are sections in that script which are
+ not assigned to it, and which occur before the first
+ use of that header. See here for more details:
+ http://sourceware.org/ml/binutils/2007-02/msg00291.html */
+ for (tmp_os = os; tmp_os; tmp_os = tmp_os->next)
+ if (tmp_os->phdrs)
+ break;
+ pl = tmp_os->phdrs;
+ }
}
if (os->bfd_section == NULL)
struct overlay_list *n;
etree_type *size;
- lang_enter_output_section_statement (name, overlay_vma, normal_section,
+ lang_enter_output_section_statement (name, overlay_vma, overlay_section,
0, overlay_subalign, 0, 0);
/* If this is the first section, then base the VMA of future
buf = xmalloc (strlen (clean) + sizeof "__load_start_");
sprintf (buf, "__load_start_%s", clean);
- lang_add_assignment (exp_assop ('=', buf,
- exp_nameop (LOADADDR, name)));
+ lang_add_assignment (exp_provide (buf,
+ exp_nameop (LOADADDR, name),
+ FALSE));
buf = xmalloc (strlen (clean) + sizeof "__load_stop_");
sprintf (buf, "__load_stop_%s", clean);
- lang_add_assignment (exp_assop ('=', buf,
- exp_binop ('+',
- exp_nameop (LOADADDR, name),
- exp_nameop (SIZEOF, name))));
+ lang_add_assignment (exp_provide (buf,
+ exp_binop ('+',
+ exp_nameop (LOADADDR, name),
+ exp_nameop (SIZEOF, name)),
+ FALSE));
free (clean);
}
The base address is not needed (and should be null) if
an LMA region was specified. */
if (l->next == 0)
- l->os->load_base = lma_expr;
-
+ {
+ l->os->load_base = lma_expr;
+ l->os->sectype = normal_section;
+ }
if (phdrs != NULL && l->os->phdrs == NULL)
l->os->phdrs = phdrs;