(stat_save, stat_save_ptr): New variables.
(lang_insert_orphan): Use push_stat_ptr and pop_stat_ptr.
(load_symbols): Likewise. Delete dead "bad_load" code.
(open_input_bfds): Warn on script containing output sections.
(lang_enter_output_section_statement): Use push_stat_ptr.
(lang_enter_group): Likewise.
(lang_leave_output_section_statement): Use pop_stat_ptr.
(lang_leave_group): Likewise.
* ldlang.h (push_stat_ptr, pop_stat_ptr): Declare.
* ldctor.c (ldctor_build_sets): Use push_stat_ptr and pop_stat_ptr.
* emultempl/beos.em (gld_${EMULATION_NAME}_set_symbols): Likewise.
* emultempl/pe.em (gld_${EMULATION_NAME}_set_symbols): Likewise.
* emultempl/pep.em (gld_${EMULATION_NAME}_set_symbols): Likewise.
* emultempl/spuelf.em (spu_place_special_section): Likewise.
* emultempl/xtensaelf.em (ld_xtensa_insert_page_offsets): Likewise.
+2009-02-16 Alan Modra <amodra@bigpond.net.au>
+
+ * ldlang.c (push_stat_ptr, pop_stat_ptr): New functions.
+ (stat_save, stat_save_ptr): New variables.
+ (lang_insert_orphan): Use push_stat_ptr and pop_stat_ptr.
+ (load_symbols): Likewise. Delete dead "bad_load" code.
+ (open_input_bfds): Warn on script containing output sections.
+ (lang_enter_output_section_statement): Use push_stat_ptr.
+ (lang_enter_group): Likewise.
+ (lang_leave_output_section_statement): Use pop_stat_ptr.
+ (lang_leave_group): Likewise.
+ * ldlang.h (push_stat_ptr, pop_stat_ptr): Declare.
+ * ldctor.c (ldctor_build_sets): Use push_stat_ptr and pop_stat_ptr.
+ * emultempl/beos.em (gld_${EMULATION_NAME}_set_symbols): Likewise.
+ * emultempl/pe.em (gld_${EMULATION_NAME}_set_symbols): Likewise.
+ * emultempl/pep.em (gld_${EMULATION_NAME}_set_symbols): Likewise.
+ * emultempl/spuelf.em (spu_place_special_section): Likewise.
+ * emultempl/xtensaelf.em (ld_xtensa_insert_page_offsets): Likewise.
+
2009-02-09 Nathan Sidwell <nathan@codesourcery.com>
Missing piece of 2009-01-26 commit
fragment <<EOF
/* This file is part of GLD, the Gnu Linker.
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of the GNU Binutils.
/* Run through and invent symbols for all the
names and insert the defaults. */
int j;
- lang_statement_list_type *save;
if (!init[IMAGEBASEOFF].inited)
{
return;
/* Glue the assignments into the abs section */
- save = stat_ptr;
-
- stat_ptr = &(abs_output_section->children);
+ push_stat_ptr (&abs_output_section->children);
for (j = 0; init[j].ptr; j++)
{
else abort();
}
/* Restore the pointer. */
- stat_ptr = save;
+ pop_stat_ptr ();
if (pe.FileAlignment >
pe.SectionAlignment)
static void
gld_${EMULATION_NAME}_before_allocation (void)
{
- extern lang_statement_list_type *stat_ptr;
-
#ifdef TARGET_IS_ppcpe
/* Here we rummage through the found bfds to collect toc information */
{
(echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-)
fragment <<EOF
/* Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of the GNU Binutils.
/* Run through and invent symbols for all the
names and insert the defaults. */
int j;
- lang_statement_list_type *save;
if (!init[IMAGEBASEOFF].inited)
{
return;
/* Glue the assignments into the abs section. */
- save = stat_ptr;
-
- stat_ptr = &(abs_output_section->children);
+ push_stat_ptr (&abs_output_section->children);
for (j = 0; init[j].ptr; j++)
{
image_base_statement = rv;
}
/* Restore the pointer. */
- stat_ptr = save;
+ pop_stat_ptr ();
if (pe.FileAlignment >
pe.SectionAlignment)
rm -f e${EMULATION_NAME}.c
(echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-)
fragment <<EOF
-/* Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+/* Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
Written by Kai Tietz, OneVision Software GmbH&CoKg.
This file is part of the GNU Binutils.
/* Run through and invent symbols for all the
names and insert the defaults. */
int j;
- lang_statement_list_type *save;
if (!init[IMAGEBASEOFF].inited)
{
return;
/* Glue the assignments into the abs section. */
- save = stat_ptr;
-
- stat_ptr = &(abs_output_section->children);
+ push_stat_ptr (&abs_output_section->children);
for (j = 0; init[j].ptr; j++)
{
image_base_statement = rv;
}
/* Restore the pointer. */
- stat_ptr = save;
+ pop_stat_ptr ();
if (pep.FileAlignment > pep.SectionAlignment)
{
/* Pad this stub section so that it finishes at the
end of the icache line. */
etree_type *e_size;
- lang_statement_list_type *save = stat_ptr;
- stat_ptr = &os->children;
+ push_stat_ptr (&os->children);
e_size = exp_intop (params.line_size - s->size);
lang_add_assignment (exp_assop ('=', ".", e_size));
- stat_ptr = save;
+ pop_stat_ptr ();
}
lang_add_section (&os->children, s, os);
}
if (lang_add_input_file (oname, lang_input_file_is_file_enum, NULL) == NULL)
return FALSE;
- /* lang_add_input_file put the new list entry at the end of the statement
+ /* lang_add_input_file puts the new list entry at the end of the statement
and input file lists. Move it to just after the current entry. */
new_ent = *old_stat_tail;
*old_stat_tail = NULL;
# This shell script emits a C file. -*- C -*-
-# Copyright 2003, 2004, 2005, 2006, 2007, 2008
+# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009
# Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
lang_assignment_statement_type *assign_stmt;
lang_statement_union_type *assign_union;
lang_statement_list_type tmplist;
- lang_statement_list_type *old_stat_ptr = stat_ptr;
/* There is hidden state in "lang_add_assignment". It
appends the new assignment statement to the stat_ptr
list. Thus, we swap it before and after the call. */
- tmplist.head = NULL;
- tmplist.tail = &tmplist.head;
-
- stat_ptr = &tmplist;
+ lang_list_init (&tmplist);
+ push_stat_ptr (&tmplist);
/* Warning: side effect; statement appended to stat_ptr. */
assign_stmt = lang_add_assignment (assign_op);
assign_union = (lang_statement_union_type *) assign_stmt;
- stat_ptr = old_stat_ptr;
+ pop_stat_ptr ();
assign_union->header.next = l;
*(*stack_p)->iterloc.loc = assign_union;
/* ldctor.c -- constructor support routines
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
By Steve Chamberlain <sac@cygnus.com>
This file is part of the GNU Binutils.
ldctor_build_sets (void)
{
static bfd_boolean called;
- lang_statement_list_type *old;
bfd_boolean header_printed;
struct set_info *p;
}
}
- old = stat_ptr;
- stat_ptr = &constructor_list;
-
- lang_list_init (stat_ptr);
+ lang_list_init (&constructor_list);
+ push_stat_ptr (&constructor_list);
header_printed = FALSE;
for (p = sets; p != NULL; p = p->next)
lang_add_data (size, exp_intop (0));
}
- stat_ptr = old;
+ pop_stat_ptr ();
}
/* Linker command language support.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of the GNU Binutils.
static const char *output_target;
static lang_statement_list_type statement_list;
static struct bfd_hash_table lang_definedness_table;
+static lang_statement_list_type *stat_save[10];
+static lang_statement_list_type **stat_save_ptr = &stat_save[0];
/* Forward declarations. */
static void exp_init_os (etree_type *);
list->tail = &list->head;
}
+void
+push_stat_ptr (lang_statement_list_type *new_ptr)
+{
+ if (stat_save_ptr >= stat_save + sizeof (stat_save) / sizeof (stat_save[0]))
+ abort ();
+ *stat_save_ptr++ = stat_ptr;
+ stat_ptr = new_ptr;
+}
+
+void
+pop_stat_ptr (void)
+{
+ if (stat_save_ptr <= stat_save)
+ abort ();
+ stat_ptr = *--stat_save_ptr;
+}
+
/* Build a new statement node for the parse tree. */
static lang_statement_union_type *
etree_type *address,
lang_statement_list_type *add_child)
{
- lang_statement_list_type *old;
lang_statement_list_type add;
const char *ps;
lang_output_section_statement_type *os;
lang_output_section_statement_type **os_tail;
- /* Start building a list of statements for this section.
- First save the current statement pointer. */
- old = stat_ptr;
-
/* If we have found an appropriate place for the output section
statements for this orphan, add them to our own private list,
inserting them later into the global statement list. */
if (after != NULL)
{
- stat_ptr = &add;
- lang_list_init (stat_ptr);
+ lang_list_init (&add);
+ push_stat_ptr (&add);
}
ps = NULL;
{
char *symname;
- /* lang_leave_ouput_section_statement resets stat_ptr.
- Put stat_ptr back where we want it. */
- if (after != NULL)
- stat_ptr = &add;
-
symname = (char *) xmalloc (ps - secname + sizeof "__stop_" + 1);
symname[0] = bfd_get_symbol_leading_char (link_info.output_bfd);
sprintf (symname + (symname[0] != 0), "__stop_%s", secname);
/* Restore the global list pointer. */
if (after != NULL)
- stat_ptr = old;
+ pop_stat_ptr ();
if (after != NULL && os->bfd_section != NULL)
{
/* Fix the global list pointer if we happened to tack our
new list at the tail. */
- if (*old->tail == add.head)
- old->tail = add.tail;
+ if (*stat_ptr->tail == add.head)
+ stat_ptr->tail = add.tail;
/* Save the end of this list. */
place->stmt = add.tail;
&& ! bfd_check_format_matches (entry->the_bfd, bfd_object, &matching))
{
bfd_error_type err;
- lang_statement_list_type *hold;
- bfd_boolean bad_load = TRUE;
bfd_boolean save_ldlang_sysrooted_script;
bfd_boolean save_as_needed, save_add_needed;
else if (err != bfd_error_file_not_recognized
|| place == NULL)
einfo (_("%F%B: file not recognized: %E\n"), entry->the_bfd);
- else
- bad_load = FALSE;
bfd_close (entry->the_bfd);
entry->the_bfd = NULL;
/* Try to interpret the file as a linker script. */
ldfile_open_command_file (entry->filename);
- hold = stat_ptr;
- stat_ptr = place;
+ push_stat_ptr (place);
save_ldlang_sysrooted_script = ldlang_sysrooted_script;
ldlang_sysrooted_script = entry->sysrooted;
save_as_needed = as_needed;
ldlang_sysrooted_script = save_ldlang_sysrooted_script;
as_needed = save_as_needed;
add_needed = save_add_needed;
- stat_ptr = hold;
+ pop_stat_ptr ();
- return ! bad_load;
+ return TRUE;
}
if (ldemul_recognized_file (entry))
case lang_input_statement_enum:
if (s->input_statement.real)
{
+ lang_statement_union_type **os_tail;
lang_statement_list_type add;
s->input_statement.target = current_target;
bfd_archive))
s->input_statement.loaded = FALSE;
+ os_tail = lang_output_section_statement.tail;
lang_list_init (&add);
if (! load_symbols (&s->input_statement, &add))
if (add.head != NULL)
{
- *add.tail = s->header.next;
- s->header.next = add.head;
+ /* If this was a script with output sections then
+ tack any added statements on to the end of the
+ list. This avoids having to reorder the output
+ section statement list. Very likely the user
+ forgot -T, and whatever we do here will not meet
+ naive user expectations. */
+ if (os_tail != lang_output_section_statement.tail)
+ {
+ einfo (_("%P: warning: %s contains output sections;"
+ " did you forget -T?\n"),
+ s->input_statement.filename);
+ *stat_ptr->tail = add.head;
+ stat_ptr->tail = add.tail;
+ }
+ else
+ {
+ *add.tail = s->header.next;
+ s->header.next = add.head;
+ }
}
}
break;
os->block_value = 1;
/* Make next things chain into subchain of this. */
- stat_ptr = &os->children;
+ push_stat_ptr (&os->children);
os->subsection_alignment =
topower (exp_get_value_int (subalign, -1, "subsection alignment"));
current_section->addr_tree != NULL);
current_section->fill = fill;
current_section->phdrs = phdrs;
- stat_ptr = &statement_list;
+ pop_stat_ptr ();
}
/* Create an absolute symbol with the given name with the value of the
g = new_stat (lang_group_statement, stat_ptr);
lang_list_init (&g->children);
- stat_ptr = &g->children;
+ push_stat_ptr (&g->children);
}
/* Leave a group. This just resets stat_ptr to start writing to the
void
lang_leave_group (void)
{
- stat_ptr = &statement_list;
+ pop_stat_ptr ();
}
/* Add a new program header. This is called for each entry in a PHDRS
/* ldlang.h - linker command language support
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of the GNU Binutils.
(const char *, const char *, const char *, int);
extern void lang_list_init
(lang_statement_list_type *);
+extern void push_stat_ptr
+ (lang_statement_list_type *);
+extern void pop_stat_ptr
+ (void);
extern void lang_add_data
(int type, union etree_union *);
extern void lang_add_reloc