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]

gold patch committed: Improve x86_64 non-PIC warnings


This gold patch improves the warnings about generating a shared library
with non-PIC code on x86_64.  A PC32 reloc against a locally defined
symbol is OK.  We report the relocation type and, for a global symbol,
the symbol name, to make it easier to find the problem.  Committed to
mainline.

Ian


2011-06-17  Ian Lance Taylor  <iant@google.com>

	* x86_64.cc (check_non_pic): Add gsym parameter.  Change all
	callers.  Don't issue warning about PC32 against locally defined
	symbol.


Index: x86_64.cc
===================================================================
RCS file: /cvs/src/src/gold/x86_64.cc,v
retrieving revision 1.126
diff -u -r1.126 x86_64.cc
--- x86_64.cc	8 Jun 2011 04:43:28 -0000	1.126
+++ x86_64.cc	17 Jun 2011 11:11:03 -0000
@@ -488,7 +488,7 @@
 			     Symbol*);
 
     void
-    check_non_pic(Relobj*, unsigned int r_type);
+    check_non_pic(Relobj*, unsigned int r_type, Symbol*);
 
     inline bool
     possible_function_pointer_reloc(unsigned int r_type);
@@ -1610,10 +1610,13 @@
 // Here we know the section is allocated, but we don't know that it is
 // read-only.  But we check for all the relocation types which the
 // glibc dynamic linker supports, so it seems appropriate to issue an
-// error even if the section is not read-only.
+// error even if the section is not read-only.  If GSYM is not NULL,
+// it is the symbol the relocation is against; if it is NULL, the
+// relocation is against a local symbol.
 
 void
-Target_x86_64::Scan::check_non_pic(Relobj* object, unsigned int r_type)
+Target_x86_64::Scan::check_non_pic(Relobj* object, unsigned int r_type,
+				   Symbol* gsym)
 {
   switch (r_type)
     {
@@ -1631,13 +1634,29 @@
       return;
 
       // glibc supports these reloc types, but they can overflow.
-    case elfcpp::R_X86_64_32:
     case elfcpp::R_X86_64_PC32:
+      // A PC relative reference is OK against a local symbol or if
+      // the symbol is defined locally.
+      if (gsym == NULL
+	  || (!gsym->is_from_dynobj()
+	      && !gsym->is_undefined()
+	      && !gsym->is_preemptible()))
+	return;
+      /* Fall through.  */
+    case elfcpp::R_X86_64_32:
       if (this->issued_non_pic_error_)
 	return;
       gold_assert(parameters->options().output_is_position_independent());
-      object->error(_("requires dynamic reloc which may overflow at runtime; "
-		      "recompile with -fPIC"));
+      if (gsym == NULL)
+	object->error(_("requires dynamic R_X86_64_32 reloc which may "
+			"overflow at runtime; recompile with -fPIC"));
+      else
+	object->error(_("requires dynamic %s reloc against '%s' which may "
+			"overflow at runtime; recompile with -fPIC"),
+		      (r_type == elfcpp::R_X86_64_32
+		       ? "R_X86_64_32"
+		       : "R_X86_64_PC32"),
+		      gsym->name());
       this->issued_non_pic_error_ = true;
       return;
 
@@ -1648,8 +1667,9 @@
       if (this->issued_non_pic_error_)
         return;
       gold_assert(parameters->options().output_is_position_independent());
-      object->error(_("requires unsupported dynamic reloc; "
-                      "recompile with -fPIC"));
+      object->error(_("requires unsupported dynamic reloc %u; "
+                      "recompile with -fPIC"),
+		    r_type);
       this->issued_non_pic_error_ = true;
       return;
 
@@ -1730,7 +1750,7 @@
       // because that is always a 64-bit relocation.
       if (parameters->options().output_is_position_independent())
         {
-          this->check_non_pic(object, r_type);
+          this->check_non_pic(object, r_type, NULL);
 
           Reloc_section* rela_dyn = target->rela_dyn_section(layout);
 	  unsigned int r_sym = elfcpp::elf_r_sym<64>(reloc.get_r_info());
@@ -1814,7 +1834,7 @@
 		  }
                 else
                   {
-                    this->check_non_pic(object, r_type);
+                    this->check_non_pic(object, r_type, NULL);
 
                     gold_assert(lsym.get_st_type() != elfcpp::STT_SECTION);
                     rela_dyn->add_local(
@@ -2135,7 +2155,7 @@
               }
             else
               {
-                this->check_non_pic(object, r_type);
+                this->check_non_pic(object, r_type, gsym);
                 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
                 rela_dyn->add_global(gsym, r_type, output_section, object,
                                      data_shndx, reloc.get_r_offset(),
@@ -2163,7 +2183,7 @@
               }
             else
               {
-                this->check_non_pic(object, r_type);
+                this->check_non_pic(object, r_type, gsym);
                 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
                 rela_dyn->add_global(gsym, r_type, output_section, object,
                                      data_shndx, reloc.get_r_offset(),

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