diff --git a/gold/ChangeLog b/gold/ChangeLog index caae10c3e2..53bc3639d2 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,14 @@ +2010-11-03 Nick Clifton + + PR gold/12001 + * script.h (class Symbol_assignment: name): New member. Returns + the name of the symbol. + * scrfipt.cc (Script_options::is_pending_assignment): New member. + Returns true if the given symbol name is on the list of + assignments wating to be processed. + * archive.cc (should_incldue_member): If the symbol is undefined, + check to see if it is on the list of symbols pending assignment. + 2010-11-03 Ryan Mansfield * script-sections.cc (Script_sections::find_memory_region): Check diff --git a/gold/archive.cc b/gold/archive.cc index 541a49456a..a289e5eaef 100644 --- a/gold/archive.cc +++ b/gold/archive.cc @@ -671,6 +671,10 @@ Archive::should_include_member(Symbol_table* symtab, Layout* layout, } else if (!sym->is_undefined()) return Archive::SHOULD_INCLUDE_NO; + // PR 12001: Do not include an archive when the undefined + // symbol has actually been defined on the command line. + else if (layout->script_options()->is_pending_assignment(sym_name)) + return Archive::SHOULD_INCLUDE_NO; else if (sym->binding() == elfcpp::STB_WEAK) return Archive::SHOULD_INCLUDE_UNKNOWN; diff --git a/gold/script.cc b/gold/script.cc index b92f85cb92..ada9abccc6 100644 --- a/gold/script.cc +++ b/gold/script.cc @@ -1050,6 +1050,20 @@ Script_options::Script_options() { } +// Returns true if NAME is on the list of symbol assignments waiting +// to be processed. + +bool +Script_options::is_pending_assignment(const char* name) +{ + for (Symbol_assignments::iterator p = this->symbol_assignments_.begin(); + p != this->symbol_assignments_.end(); + ++p) + if ((*p)->name() == name) + return true; + return false; +} + // Add a symbol to be defined. void diff --git a/gold/script.h b/gold/script.h index 70e3a59e7b..e1134ca286 100644 --- a/gold/script.h +++ b/gold/script.h @@ -345,6 +345,10 @@ class Symbol_assignment set_if_absolute(Symbol_table*, const Layout*, bool is_dot_available, uint64_t dot_value); + const std::string& + name() const + { return this->name_; } + // Print the assignment to the FILE. This is for debugging. void print(FILE*) const; @@ -423,6 +427,10 @@ class Script_options add_symbol_assignment(const char* name, size_t length, bool is_defsym, Expression* value, bool provide, bool hidden); + // Look for an assigned symbol. + bool + is_pending_assignment(const char* name); + // Add a reference to a symbol. void add_symbol_reference(const char* name, size_t length); diff --git a/ld/ChangeLog b/ld/ChangeLog index 538f32de3f..b6cada28aa 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,17 @@ +2010-11-03 Nick Clifton + + PR ld/12001 + * ldlang.c (ldlang_def_chain_list): New variable. Contains a list + of symbols defined via the --defsym command line option and + currently waiting assignment. + (insert_defined): Add a defined symbol to the symbol table. + (ldlang_add_def): Add a entry to the ldlang_def_chain_list. + (lang_place_defineds): Walk ldlang_def_chain_list defining the + symbols. + (lang_process): Call lang_place_defineds. + (lang_add_assignment): If the assignment has come from a --defsym + command line option then call lang_add_def. + 2010-11-03 Alan Modra * Makefile.am (eelf64hppa.c): Correct dependencies. diff --git a/ld/ldlang.c b/ld/ldlang.c index 95ef5f5d96..798d7a1109 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -3344,6 +3344,65 @@ lang_place_undefineds (void) insert_undefined (ptr->name); } +typedef struct bfd_sym_chain ldlang_def_chain_list_type; + +static ldlang_def_chain_list_type ldlang_def_chain_list_head; + +/* Insert NAME as defined in the symbol table. */ + +static void +insert_defined (const char *name) +{ + struct bfd_link_hash_entry *h; + + h = bfd_link_hash_lookup (link_info.hash, name, TRUE, FALSE, TRUE); + if (h == NULL) + einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); + if (h->type == bfd_link_hash_new + || h->type == bfd_link_hash_undefined + || h->type == bfd_link_hash_undefweak) + { + h->type = bfd_link_hash_defined; + h->u.def.section = bfd_abs_section_ptr; + h->u.def.value = 0; + } +} + +/* Like lang_add_undef, but this time for symbols defined on the + command line. */ + +static void +ldlang_add_def (const char *const name) +{ + if (link_info.output_bfd != NULL) + insert_defined (xstrdup (name)); + else + { + ldlang_def_chain_list_type *new_def; + + new_def = (ldlang_def_chain_list_type *) stat_alloc (sizeof (*new_def)); + new_def->next = ldlang_def_chain_list_head.next; + ldlang_def_chain_list_head.next = new_def; + + new_def->name = xstrdup (name); + } +} + +/* Run through the list of defineds created above and place them + into the linker hash table as defined symbols belonging to the + script file. */ + +static void +lang_place_defineds (void) +{ + ldlang_def_chain_list_type *ptr; + + for (ptr = ldlang_def_chain_list_head.next; + ptr != NULL; + ptr = ptr->next) + insert_defined (ptr->name); +} + /* Check for all readonly or some readwrite sections. */ static void @@ -6350,6 +6409,7 @@ lang_process (void) /* Add to the hash table all undefineds on the command line. */ lang_place_undefineds (); + lang_place_defineds (); if (!bfd_section_already_linked_table_init ()) einfo (_("%P%F: Failed to create hash table\n")); @@ -6634,6 +6694,10 @@ lang_add_assignment (etree_type *exp) { lang_assignment_statement_type *new_stmt; + extern int parsing_defsym; + if (parsing_defsym) + ldlang_add_def (exp->assign.dst); + new_stmt = new_stat (lang_assignment_statement, stat_ptr); new_stmt->exp = exp; return new_stmt; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 8d49e4ab8a..1bbde6202c 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-11-03 Nick Clifton + + PR ld/12001 + * ld-script/default-script2.d: Fix expected address for text + section. + 2010-11-02 Joseph Myers * ld-tic6x/attr-array-16-16.d, ld-tic6x/attr-array-16-4.d, diff --git a/ld/testsuite/ld-scripts/default-script2.d b/ld/testsuite/ld-scripts/default-script2.d index 68ce2aa9fe..829718d8a9 100644 --- a/ld/testsuite/ld-scripts/default-script2.d +++ b/ld/testsuite/ld-scripts/default-script2.d @@ -5,5 +5,5 @@ #... 0*8000000 . _START #... -0*9000000 T text +0*8000000 T text #pass