* sparc.cc (Target_sparc::Scan::local): Do not emit relocs other than
authorDavid S. Miller <davem@redhat.com>
Tue, 9 Feb 2010 20:05:19 +0000 (20:05 +0000)
committerDavid S. Miller <davem@redhat.com>
Tue, 9 Feb 2010 20:05:19 +0000 (20:05 +0000)
R_SPARC_RELATIVE using ->add_local_relative().
(Target_sparc::Scan::global): Likewise for ->add_global_relative().

gold/ChangeLog
gold/sparc.cc

index 534ff1d51d0fc8dfc626bdfe5a9c88cc67fc2522..c2daecdd28171fa468dac0a31b3c7cbf3b3aab9e 100644 (file)
@@ -1,3 +1,9 @@
+2010-02-09  David S. Miller  <davem@davemloft.net>
+
+       * sparc.cc (Target_sparc::Scan::local): Do not emit relocs other than
+       R_SPARC_RELATIVE using ->add_local_relative().
+       (Target_sparc::Scan::global): Likewise for ->add_global_relative().
+
 2010-02-08  Doug Kwan  <dougkwan@google.com>
 
        * arm.cc (Arm_relobj::simple_input_section_output_address): New
index 9bca176ce7e0976508433e771431ec7952db1da9..503cd8bb6bd327cca0d50196f4cfd165170fe6df 100644 (file)
@@ -1670,23 +1670,31 @@ Target_sparc<size, big_endian>::Scan::local(
       if (parameters->options().output_is_position_independent())
         {
           Reloc_section* rela_dyn = target->rela_dyn_section(layout);
+          unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
 
          check_non_pic(object, r_type);
           if (lsym.get_st_type() != elfcpp::STT_SECTION)
             {
-              unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
               rela_dyn->add_local(object, r_sym, orig_r_type, output_section,
                                  data_shndx, reloc.get_r_offset(),
                                  reloc.get_r_addend());
             }
           else
             {
-             unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
+             unsigned int shndx = lsym.get_st_shndx();
+             bool is_ordinary;
+
               gold_assert(lsym.get_st_value() == 0);
-              rela_dyn->add_local_relative(object, r_sym, orig_r_type,
-                                          output_section, data_shndx,
-                                          reloc.get_r_offset(),
-                                          reloc.get_r_addend());
+             shndx = object->adjust_sym_shndx(r_sym, shndx,
+                                              &is_ordinary);
+             if (!is_ordinary)
+               object->error(_("section symbol %u has bad shndx %u"),
+                             r_sym, shndx);
+             else
+               rela_dyn->add_local_section(object, shndx,
+                                           r_type, output_section,
+                                           data_shndx, reloc.get_r_offset(),
+                                           reloc.get_r_addend());
             }
         }
       break;
@@ -1834,15 +1842,13 @@ Target_sparc<size, big_endian>::Scan::local(
                if (!object->local_has_got_offset(r_sym, GOT_TYPE_TLS_OFFSET))
                  {
                    Reloc_section* rela_dyn = target->rela_dyn_section(layout);
-                   unsigned int off = got->add_constant(0);
-
-                   object->set_local_got_offset(r_sym, GOT_TYPE_TLS_OFFSET,
-                                                off);
-                   rela_dyn->add_local_relative(object, r_sym,
-                                                (size == 64 ?
-                                                 elfcpp::R_SPARC_TLS_TPOFF64 :
-                                                 elfcpp::R_SPARC_TLS_TPOFF32),
-                                                got, off, 0);
+
+                   got->add_local_with_rela(object, r_sym,
+                                            GOT_TYPE_TLS_OFFSET,
+                                            rela_dyn,
+                                            (size == 64 ?
+                                             elfcpp::R_SPARC_TLS_TPOFF64 :
+                                             elfcpp::R_SPARC_TLS_TPOFF32));
                  }
              }
            else if (optimized_type != tls::TLSOPT_TO_LE)
@@ -1858,9 +1864,9 @@ Target_sparc<size, big_endian>::Scan::local(
                 gold_assert(lsym.get_st_type() != elfcpp::STT_SECTION);
                 unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
                 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
-                rela_dyn->add_local_relative(object, r_sym, r_type,
-                                            output_section, data_shndx,
-                                            reloc.get_r_offset(), 0);
+                rela_dyn->add_local(object, r_sym, r_type,
+                                   output_section, data_shndx,
+                                   reloc.get_r_offset(), 0);
              }
            break;
          }
@@ -2055,19 +2061,10 @@ Target_sparc<size, big_endian>::Scan::global(
                 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
 
                check_non_pic(object, r_type);
-               if (gsym->is_from_dynobj()
-                   || gsym->is_undefined()
-                   || gsym->is_preemptible())
-                 rela_dyn->add_global(gsym, orig_r_type, output_section,
-                                      object, data_shndx,
-                                      reloc.get_r_offset(),
-                                      reloc.get_r_addend());
-               else
-                 rela_dyn->add_global_relative(gsym, orig_r_type,
-                                               output_section, object,
-                                               data_shndx,
-                                               reloc.get_r_offset(),
-                                               reloc.get_r_addend());
+               rela_dyn->add_global(gsym, orig_r_type, output_section,
+                                    object, data_shndx,
+                                    reloc.get_r_offset(),
+                                    reloc.get_r_addend());
               }
           }
       }
@@ -2199,10 +2196,10 @@ Target_sparc<size, big_endian>::Scan::global(
            if (parameters->options().shared())
              {
                Reloc_section* rela_dyn = target->rela_dyn_section(layout);
-               rela_dyn->add_global_relative(gsym, orig_r_type,
-                                             output_section, object,
-                                             data_shndx, reloc.get_r_offset(),
-                                             0);
+               rela_dyn->add_global(gsym, orig_r_type,
+                                    output_section, object,
+                                    data_shndx, reloc.get_r_offset(),
+                                    0);
              }
            break;