This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Properly convert address load of __start_XXX/__stop_XXX


On Mon, Oct 26, 2015 at 08:17:44AM -0700, H.J. Lu wrote:
+bfd_boolean
> +bfd_link_get_defined_symbol (struct bfd_link_info *info,
> +			     struct bfd_link_hash_entry *h,
> +			     asection **sec, bfd_vma *value)

I think we can do better than this inelegant solution.  The underlying
problem is that the linker does not define __start_* and __stop_*
before sizing dynamic sections.  Orphan sections are placed before
sizing dynamic sections, but lang_insert_orphan arranges to define
the symbols by adding script PROVIDE statements, and these are not
evaluated until later.

So it ought to be a simple matter of evaluating those PROVIDE
statements.

Ah, I see you have already reverted bfd_link_get_defined_symbol.
This patch should mean you don't need the bfd_link_hash_new checks.

commit 6762151f758394fe2550760f6fd6fb5748a59b33
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Oct 27 12:01:55 2015 +1030

    Evaluate __start_* and __stop_* symbol PROVIDE expressions early
    
    Makes these symbols defined before bfd_elf_size_dynamic_sections, to
    avoid horrible hacks elsewhere.  The exp_fold_tree undefweak change
    is necessary to define undefweak symbols early too.  The comment was
    wrong.  PROVIDE in fact defines undefweak symbols, via
    bfd_elf_record_link_assignment.
    
    	PR ld/19175
    	* ldlang.c (lang_insert_orphan): Evaluate __start_* and __stop_*
    	symbol PROVIDE expressions.
    	* ldexp.c (exp_fold_tree_1 <etree_provide>): Define undefweak
    	references.

diff --git a/ld/ChangeLog b/ld/ChangeLog
index 2cb506a..bef7b26 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,11 @@
+2015-10-27  Alan Modra  <amodra@gmail.com>
+
+	PR ld/19175
+	* ldlang.c (lang_insert_orphan): Evaluate __start_* and __stop_*
+	symbol PROVIDE expressions.
+	* ldexp.c (exp_fold_tree_1 <etree_provide>): Define undefweak
+	references.
+
 2015-10-22  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* configure.ac: Properly check
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 7694f7b..2ec8eb6 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -1126,11 +1126,14 @@ exp_fold_tree_1 (etree_type *tree)
 	      if (h == NULL
 		  || !(h->type == bfd_link_hash_new
 		       || h->type == bfd_link_hash_undefined
+		       || h->type == bfd_link_hash_undefweak
 		       || h->linker_def))
 		{
 		  /* Do nothing.  The symbol was never referenced, or
-		     was defined in some object file.  Undefined weak
-		     symbols stay undefined.  */
+		     was defined in some object file.  Note that
+		     undefweak symbols are defined by PROVIDE.  This
+		     is to support glibc use of __rela_iplt_start and
+		     similar weak references.  */
 		  break;
 		}
 	    }
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 2986981..5c7ea9f 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -1805,6 +1805,7 @@ lang_insert_orphan (asection *s,
 {
   lang_statement_list_type add;
   const char *ps;
+  lang_assignment_statement_type *start_assign;
   lang_output_section_statement_type *os;
   lang_output_section_statement_type **os_tail;
 
@@ -1827,6 +1828,7 @@ lang_insert_orphan (asection *s,
 					    NULL, NULL, NULL, constraint, 0);
 
   ps = NULL;
+  start_assign = NULL;
   if (config.build_constructors && *os_tail == os)
     {
       /* If the name of the section is representable in C, then create
@@ -1841,9 +1843,10 @@ lang_insert_orphan (asection *s,
 	  symname = (char *) xmalloc (ps - secname + sizeof "__start_" + 1);
 	  symname[0] = bfd_get_symbol_leading_char (link_info.output_bfd);
 	  sprintf (symname + (symname[0] != 0), "__start_%s", secname);
-	  lang_add_assignment (exp_provide (symname,
-					    exp_nameop (NAME, "."),
-					    FALSE));
+	  start_assign
+	    = lang_add_assignment (exp_provide (symname,
+						exp_nameop (NAME, "."),
+						FALSE));
 	}
     }
 
@@ -1866,16 +1869,25 @@ lang_insert_orphan (asection *s,
     lang_leave_output_section_statement (NULL, DEFAULT_MEMORY_REGION, NULL,
 					 NULL);
 
-  if (ps != NULL && *ps == '\0')
+  if (start_assign != NULL)
     {
       char *symname;
+      lang_assignment_statement_type *stop_assign;
+      bfd_vma dot;
 
       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);
-      lang_add_assignment (exp_provide (symname,
-					exp_nameop (NAME, "."),
-					FALSE));
+      stop_assign
+	= lang_add_assignment (exp_provide (symname,
+					    exp_nameop (NAME, "."),
+					    FALSE));
+      /* Evaluate the expression to define the symbol if referenced,
+	 before sizing dynamic sections.  */
+      dot = os->bfd_section->vma;
+      exp_fold_tree (start_assign->exp, os->bfd_section, &dot);
+      dot += s->size;
+      exp_fold_tree (stop_assign->exp, os->bfd_section, &dot);
     }
 
   /* Restore the global list pointer.  */

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]