From 66c103b772fdbc413d4727efa329babcab6617c5 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sun, 7 Sep 2008 04:02:31 +0000 Subject: * ldlang.h (lang_output_section_find): Define. (lang_output_section_statement_lookup): Update prototype. * ldlang.c (lang_output_section_find, lang_output_section_statement_lookup_1): Merge into.. (lang_output_section_statement_lookup): ..here. Update all callers. (process_insert_statements): Set constraint negative for output section statements we might be inserting. Make error fatal on not finding insertion section. (lang_output_section_find): Rather than comparing output_section_statement.constraint against -1, test whether it is postive. (lang_output_section_statement_lookup_1): Likewise. (output_prev_sec_find, strip_excluded_output_sections): Likewise. (lang_record_phdrs): Likewise. * emultempl/elf32.em (output_rel_find): Likewise. * NEWS: Mention INSERT. --- ld/ChangeLog | 19 +++++++++ ld/NEWS | 11 +++-- ld/emultempl/elf32.em | 2 +- ld/ldlang.c | 114 ++++++++++++++++++++------------------------------ ld/ldlang.h | 10 ++--- 5 files changed, 78 insertions(+), 78 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 8123c0a93fa..2f49f6b182d 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,22 @@ +2008-09-07 Alan Modra + + * ldlang.h (lang_output_section_find): Define. + (lang_output_section_statement_lookup): Update prototype. + * ldlang.c (lang_output_section_find, + lang_output_section_statement_lookup_1): Merge into.. + (lang_output_section_statement_lookup): ..here. Update all callers. + (process_insert_statements): Set constraint negative + for output section statements we might be inserting. Make error + fatal on not finding insertion section. + (lang_output_section_find): Rather than comparing + output_section_statement.constraint against -1, test whether + it is postive. + (lang_output_section_statement_lookup_1): Likewise. + (output_prev_sec_find, strip_excluded_output_sections): Likewise. + (lang_record_phdrs): Likewise. + * emultempl/elf32.em (output_rel_find): Likewise. + * NEWS: Mention INSERT. + 2008-08-26 Nick Clifton PR 6727 diff --git a/ld/NEWS b/ld/NEWS index c7648a08635..13eac984d30 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -1,6 +1,9 @@ -*- text -*- +* Linker scripts support a new INSERT command that makes it easier to + augment the default script. + * Linker script input section filespecs may now specify a file within an - archive by writing "archive:file". + archive by writing "archive:file". * The --sort-common switch now has an optional argument which specifies the direction of sorting. @@ -8,9 +11,9 @@ * The M68K linker now supports multiple GOT generation schemes controlled via the --got= command line option. -* The ARM EABI linker will now generate stubs for function calls to symbols that - are too far away. The placement of the stubs is controlled by a new linker - command line option: --stub-group-size=N. +* The ARM EABI linker will now generate stubs for function calls to symbols + that are too far away. The placement of the stubs is controlled by a new + linker command line option: --stub-group-size=N. Changes in 2.18: diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 955fc9fdfe2..be9d78d2eff 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -1583,7 +1583,7 @@ output_rel_find (asection *sec, int isdyn) lookup != NULL; lookup = lookup->next) { - if (lookup->constraint != -1 + if (lookup->constraint >= 0 && CONST_STRNEQ (lookup->name, ".rel")) { int lookrela = lookup->name[4] == 'a'; diff --git a/ld/ldlang.c b/ld/ldlang.c index 8d95254564f..b1b88062b02 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1149,7 +1149,7 @@ lang_init (void) first_file = lang_add_input_file (NULL, lang_input_file_is_marker_enum, NULL); abs_output_section = - lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME); + lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME, 0, TRUE); abs_output_section->bfd_section = bfd_abs_section_ptr; @@ -1255,44 +1255,19 @@ lang_memory_default (asection *section) } lang_output_section_statement_type * -lang_output_section_find (const char *const name) +lang_output_section_statement_lookup (const char *const name, + int constraint, + bfd_boolean create) { struct out_section_hash_entry *entry; - unsigned long hash; entry = ((struct out_section_hash_entry *) bfd_hash_lookup (&output_section_statement_table, name, - FALSE, FALSE)); + create, FALSE)); if (entry == NULL) - return NULL; - - hash = entry->root.hash; - do { - if (entry->s.output_section_statement.constraint != -1) - return &entry->s.output_section_statement; - entry = (struct out_section_hash_entry *) entry->root.next; - } - while (entry != NULL - && entry->root.hash == hash - && strcmp (name, entry->s.output_section_statement.name) == 0); - - return NULL; -} - -static lang_output_section_statement_type * -lang_output_section_statement_lookup_1 (const char *const name, int constraint) -{ - struct out_section_hash_entry *entry; - struct out_section_hash_entry *last_ent; - unsigned long hash; - - entry = ((struct out_section_hash_entry *) - bfd_hash_lookup (&output_section_statement_table, name, - TRUE, FALSE)); - if (entry == NULL) - { - einfo (_("%P%F: failed creating section `%s': %E\n"), name); + if (create) + einfo (_("%P%F: failed creating section `%s': %E\n"), name); return NULL; } @@ -1300,10 +1275,12 @@ lang_output_section_statement_lookup_1 (const char *const name, int constraint) { /* We have a section of this name, but it might not have the correct constraint. */ - hash = entry->root.hash; + struct out_section_hash_entry *last_ent; + unsigned long hash = entry->root.hash; + do { - if (entry->s.output_section_statement.constraint != -1 + if (entry->s.output_section_statement.constraint >= 0 && (constraint == 0 || (constraint == entry->s.output_section_statement.constraint && constraint != SPECIAL))) @@ -1315,6 +1292,9 @@ lang_output_section_statement_lookup_1 (const char *const name, int constraint) && entry->root.hash == hash && strcmp (name, entry->s.output_section_statement.name) == 0); + if (!create) + return NULL; + entry = ((struct out_section_hash_entry *) output_section_statement_newfunc (NULL, @@ -1334,12 +1314,6 @@ lang_output_section_statement_lookup_1 (const char *const name, int constraint) return &entry->s.output_section_statement; } -lang_output_section_statement_type * -lang_output_section_statement_lookup (const char *const name) -{ - return lang_output_section_statement_lookup_1 (name, 0); -} - /* A variant of lang_output_section_find used by place_orphan. Returns the output statement that should precede a new output statement for SEC. If an exact match is found on certain flags, @@ -1502,7 +1476,7 @@ output_prev_sec_find (lang_output_section_statement_type *os) for (lookup = os->prev; lookup != NULL; lookup = lookup->prev) { - if (lookup->constraint == -1) + if (lookup->constraint < 0) continue; if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL) @@ -3378,7 +3352,7 @@ map_input_to_output_sections { lang_output_section_statement_type *aos = (lang_output_section_statement_lookup - (s->address_statement.section_name)); + (s->address_statement.section_name, 0, TRUE)); if (aos->bfd_section == NULL) init_os (aos, NULL, 0); @@ -3403,6 +3377,7 @@ process_insert_statements (void) lang_statement_union_type **s; lang_output_section_statement_type *first_os = NULL; lang_output_section_statement_type *last_os = NULL; + lang_output_section_statement_type *os; /* "start of list" is actually the statement immediately after the special abs_section output statement, so that it isn't @@ -3415,6 +3390,12 @@ process_insert_statements (void) /* Keep pointers to the first and last output section statement in the sequence we may be about to move. */ last_os = &(*s)->output_section_statement; + + /* Set constraint negative so that lang_output_section_find + won't match this output section statement. At this + stage in linking constraint has values in the range + [-1, ONLY_IN_RW]. */ + last_os->constraint = -2 - last_os->constraint; if (first_os == NULL) first_os = last_os; } @@ -3422,7 +3403,6 @@ process_insert_statements (void) { lang_insert_statement_type *i = &(*s)->insert_statement; lang_output_section_statement_type *where; - lang_output_section_statement_type *os; lang_statement_union_type **ptr; lang_statement_union_type *first; @@ -3431,21 +3411,12 @@ process_insert_statements (void) { do where = where->prev; - while (where != NULL && where->constraint == -1); + while (where != NULL && where->constraint < 0); } if (where == NULL) { - einfo (_("%X%P: %s not found for insert\n"), i->where); - continue; - } - /* You can't insert into the list you are moving. */ - for (os = first_os; os != NULL; os = os->next) - if (os == where || os == last_os) - break; - if (os == where) - { - einfo (_("%X%P: %s not found for insert\n"), i->where); - continue; + einfo (_("%F%P: %s not found for insert\n"), i->where); + return; } /* Deal with reordering the output section statement list. */ @@ -3482,6 +3453,7 @@ process_insert_statements (void) last_sec = NULL; for (os = first_os; os != NULL; os = os->next) { + os->constraint = -2 - os->constraint; if (os->bfd_section != NULL && os->bfd_section->owner != NULL) { @@ -3542,6 +3514,14 @@ process_insert_statements (void) s = &lang_output_section_statement.head; } } + + /* Undo constraint twiddling. */ + for (os = first_os; os != NULL; os = os->next) + { + os->constraint = -2 - os->constraint; + if (os == last_os) + break; + } } /* An output section might have been removed after its statement was @@ -3569,7 +3549,7 @@ strip_excluded_output_sections (void) asection *output_section; bfd_boolean exclude; - if (os->constraint == -1) + if (os->constraint < 0) continue; output_section = os->bfd_section; @@ -5665,11 +5645,9 @@ lang_place_orphans (void) || command_line.force_common_definition) { if (default_common_section == NULL) - { - default_common_section = - lang_output_section_statement_lookup (".bss"); - - } + default_common_section + = lang_output_section_statement_lookup (".bss", 0, + TRUE); lang_add_section (&default_common_section->children, s, default_common_section); } @@ -5680,7 +5658,7 @@ lang_place_orphans (void) { lang_output_section_statement_type *os; - os = lang_output_section_statement_lookup (s->name); + os = lang_output_section_statement_lookup (s->name, 0, TRUE); lang_add_section (&os->children, s, os); } } @@ -5827,12 +5805,10 @@ lang_enter_output_section_statement (const char *output_section_statement_name, { lang_output_section_statement_type *os; - os = lang_output_section_statement_lookup_1 (output_section_statement_name, - constraint); + os = lang_output_section_statement_lookup (output_section_statement_name, + constraint, TRUE); current_section = os; - /* Make next things chain into subchain of this. */ - if (os->addr_tree == NULL) { os->addr_tree = address_exp; @@ -5843,6 +5819,8 @@ lang_enter_output_section_statement (const char *output_section_statement_name, else os->flags = SEC_NEVER_LOAD; os->block_value = 1; + + /* Make next things chain into subchain of this. */ stat_ptr = &os->children; os->subsection_alignment = @@ -6639,7 +6617,7 @@ lang_record_phdrs (void) { lang_output_section_phdr_list *pl; - if (os->constraint == -1) + if (os->constraint < 0) continue; pl = os->phdrs; @@ -6720,7 +6698,7 @@ lang_record_phdrs (void) { lang_output_section_phdr_list *pl; - if (os->constraint == -1 + if (os->constraint < 0 || os->bfd_section == NULL) continue; diff --git a/ld/ldlang.h b/ld/ldlang.h index 48461977c80..8b652a8d785 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -525,12 +525,13 @@ extern void lang_do_assignments statement != (lang_input_statement_type *) NULL; \ statement = (lang_input_statement_type *) statement->next) \ +#define lang_output_section_find(NAME) \ + lang_output_section_statement_lookup (NAME, 0, FALSE) + extern void lang_process (void); extern void ldlang_add_file (lang_input_statement_type *); -extern lang_output_section_statement_type *lang_output_section_find - (const char * const); extern lang_output_section_statement_type *lang_output_section_find_by_flags (const asection *, lang_output_section_statement_type **, lang_match_sec_type_func); @@ -541,9 +542,8 @@ extern lang_input_statement_type *lang_add_input_file (const char *, lang_input_file_enum_type, const char *); extern void lang_add_keepsyms_file (const char *); -extern lang_output_section_statement_type * - lang_output_section_statement_lookup - (const char *const); +extern lang_output_section_statement_type *lang_output_section_statement_lookup + (const char *const, int, bfd_boolean); extern void ldlang_add_undef (const char *const); extern void lang_add_output_format -- cgit v1.2.1