From bde18da45e5dea021d600aadeab702a6f7e31cb2 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 16 Feb 2009 07:25:52 +0000 Subject: [PATCH] * 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. --- ld/ChangeLog | 19 +++++++++ ld/emultempl/beos.em | 11 ++---- ld/emultempl/pe.em | 9 ++--- ld/emultempl/pep.em | 9 ++--- ld/emultempl/spuelf.em | 7 ++-- ld/emultempl/xtensaelf.em | 11 ++---- ld/ldctor.c | 12 +++--- ld/ldlang.c | 83 +++++++++++++++++++++++++-------------- ld/ldlang.h | 6 ++- 9 files changed, 98 insertions(+), 69 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 73020cfcd3..0636f10ba4 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,22 @@ +2009-02-16 Alan Modra + + * 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 Missing piece of 2009-01-26 commit diff --git a/ld/emultempl/beos.em b/ld/emultempl/beos.em index e417693871..370dbacd0b 100644 --- a/ld/emultempl/beos.em +++ b/ld/emultempl/beos.em @@ -8,7 +8,7 @@ fi fragment <children); + push_stat_ptr (&abs_output_section->children); for (j = 0; init[j].ptr; j++) { @@ -367,7 +364,7 @@ gld_${EMULATION_NAME}_set_symbols (void) else abort(); } /* Restore the pointer. */ - stat_ptr = save; + pop_stat_ptr (); if (pe.FileAlignment > pe.SectionAlignment) @@ -609,8 +606,6 @@ sort_sections (lang_statement_union_type *s) 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 */ { diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index d2d34adb95..858f6da76d 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -10,7 +10,7 @@ rm -f e${EMULATION_NAME}.c (echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-) fragment <children); + push_stat_ptr (&abs_output_section->children); for (j = 0; init[j].ptr; j++) { @@ -772,7 +769,7 @@ gld_${EMULATION_NAME}_set_symbols (void) image_base_statement = rv; } /* Restore the pointer. */ - stat_ptr = save; + pop_stat_ptr (); if (pe.FileAlignment > pe.SectionAlignment) diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em index f6f802e12e..559773a740 100644 --- a/ld/emultempl/pep.em +++ b/ld/emultempl/pep.em @@ -9,7 +9,7 @@ fi rm -f e${EMULATION_NAME}.c (echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-) fragment <children); + push_stat_ptr (&abs_output_section->children); for (j = 0; init[j].ptr; j++) { @@ -728,7 +725,7 @@ gld_${EMULATION_NAME}_set_symbols (void) image_base_statement = rv; } /* Restore the pointer. */ - stat_ptr = save; + pop_stat_ptr (); if (pep.FileAlignment > pep.SectionAlignment) { diff --git a/ld/emultempl/spuelf.em b/ld/emultempl/spuelf.em index 376889a6d4..396fe807f4 100644 --- a/ld/emultempl/spuelf.em +++ b/ld/emultempl/spuelf.em @@ -160,12 +160,11 @@ spu_place_special_section (asection *s, asection *o, const char *output_name) /* 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); } @@ -558,7 +557,7 @@ embedded_spu_file (lang_input_statement_type *entry, const char *flags) 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; diff --git a/ld/emultempl/xtensaelf.em b/ld/emultempl/xtensaelf.em index 6651a50c96..acc3290982 100644 --- a/ld/emultempl/xtensaelf.em +++ b/ld/emultempl/xtensaelf.em @@ -1,5 +1,5 @@ # 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. @@ -1951,20 +1951,17 @@ ld_xtensa_insert_page_offsets (bfd_vma dot, 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; diff --git a/ld/ldctor.c b/ld/ldctor.c index 12adcecc94..28e5ddb1f0 100644 --- a/ld/ldctor.c +++ b/ld/ldctor.c @@ -1,6 +1,7 @@ /* 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 This file is part of the GNU Binutils. @@ -198,7 +199,6 @@ void ldctor_build_sets (void) { static bfd_boolean called; - lang_statement_list_type *old; bfd_boolean header_printed; struct set_info *p; @@ -244,10 +244,8 @@ ldctor_build_sets (void) } } - 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) @@ -372,5 +370,5 @@ ldctor_build_sets (void) lang_add_data (size, exp_intop (0)); } - stat_ptr = old; + pop_stat_ptr (); } diff --git a/ld/ldlang.c b/ld/ldlang.c index 095bb3f0d0..0bd82cb24a 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1,6 +1,6 @@ /* 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. @@ -64,6 +64,8 @@ static const char *current_target; 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 *); @@ -925,6 +927,23 @@ lang_list_init (lang_statement_list_type *list) 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 * @@ -1586,23 +1605,18 @@ lang_insert_orphan (asection *s, 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; @@ -1648,11 +1662,6 @@ lang_insert_orphan (asection *s, { 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); @@ -1663,7 +1672,7 @@ lang_insert_orphan (asection *s, /* Restore the global list pointer. */ if (after != NULL) - stat_ptr = old; + pop_stat_ptr (); if (after != NULL && os->bfd_section != NULL) { @@ -1749,8 +1758,8 @@ lang_insert_orphan (asection *s, /* 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; @@ -2481,8 +2490,6 @@ load_symbols (lang_input_statement_type *entry, && ! 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; @@ -2505,8 +2512,6 @@ load_symbols (lang_input_statement_type *entry, 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; @@ -2514,8 +2519,7 @@ load_symbols (lang_input_statement_type *entry, /* 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; @@ -2534,9 +2538,9 @@ load_symbols (lang_input_statement_type *entry, 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)) @@ -3008,6 +3012,7 @@ open_input_bfds (lang_statement_union_type *s, bfd_boolean force) 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; @@ -3023,6 +3028,7 @@ open_input_bfds (lang_statement_union_type *s, bfd_boolean force) 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)) @@ -3030,8 +3036,25 @@ open_input_bfds (lang_statement_union_type *s, bfd_boolean force) 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; @@ -5860,7 +5883,7 @@ lang_enter_output_section_statement (const char *output_section_statement_name, 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")); @@ -6468,7 +6491,7 @@ lang_leave_output_section_statement (fill_type *fill, const char *memspec, 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 @@ -6585,7 +6608,7 @@ lang_enter_group (void) 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 @@ -6596,7 +6619,7 @@ lang_enter_group (void) 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 diff --git a/ld/ldlang.h b/ld/ldlang.h index fd0465ea1a..daf125583e 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -1,6 +1,6 @@ /* 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. @@ -550,6 +550,10 @@ extern void lang_add_output_format (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 -- 2.34.1