PR ld/12001
authorNick Clifton <nickc@redhat.com>
Wed, 3 Nov 2010 17:18:23 +0000 (17:18 +0000)
committerNick Clifton <nickc@redhat.com>
Wed, 3 Nov 2010 17:18:23 +0000 (17:18 +0000)
        * 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.

        * ld-script/default-script2.d: Fix expected address for text
        section.

        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.

gold/ChangeLog
gold/archive.cc
gold/script.cc
gold/script.h
ld/ChangeLog
ld/ldlang.c
ld/testsuite/ChangeLog
ld/testsuite/ld-scripts/default-script2.d

index caae10c3e20332ad50c647a4663a6e112de6ee04..53bc3639d271258252698205b4bfdef66826f3fb 100644 (file)
@@ -1,3 +1,14 @@
+2010-11-03  Nick Clifton  <nickc@redhat.com>
+
+       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  <rmansfield@qnx.com>
 
        * script-sections.cc (Script_sections::find_memory_region): Check
index 541a49456a51a672fef7a2df0db95930b3ee5976..a289e5eaeff1f4a7007438c93ffef7a152a555a4 100644 (file)
@@ -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;
 
index b92f85cb9239a0a472a5c49ca16ff5eb08c38cd3..ada9abccc690fd927eef94c4e6d95713b71090ce 100644 (file)
@@ -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
index 70e3a59e7b44814caecd08017dacea5f94518a1e..e1134ca2861d38b01fff4efe6ac6999aaa6970bf 100644 (file)
@@ -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);
index 538f32de3fa9e03785179e695bff3608ac17e6e7..b6cada28aadfa0127992057aa3388b23402e7ef7 100644 (file)
@@ -1,3 +1,17 @@
+2010-11-03  Nick Clifton  <nickc@redhat.com>
+
+       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  <amodra@gmail.com>
 
        * Makefile.am (eelf64hppa.c): Correct dependencies.
index 95ef5f5d9600de462d0bf4eb65610c3a0525952f..798d7a1109712033d7764e2ef8e59351476d89b2 100644 (file)
@@ -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;
index 8d49e4ab8a7ccdc5bf9b9bd24c18275f072f0403..1bbde6202c8a3c9523b2dde6a5eaca05572b565a 100644 (file)
@@ -1,3 +1,9 @@
+2010-11-03  Nick Clifton  <nickc@redhat.com>
+
+       PR ld/12001
+       * ld-script/default-script2.d: Fix expected address for text
+       section.
+
 2010-11-02  Joseph Myers  <joseph@codesourcery.com>
 
        * ld-tic6x/attr-array-16-16.d, ld-tic6x/attr-array-16-4.d,
index 68ce2aa9fe2e75703ff4e12f0625a12f861c10f4..829718d8a9795a2b64576012ff5ebb5c01b19620 100644 (file)
@@ -5,5 +5,5 @@
 #...
 0*8000000 . _START
 #...
-0*9000000 T text
+0*8000000 T text
 #pass