diff options
-rw-r--r-- | gold/ChangeLog | 6 | ||||
-rw-r--r-- | gold/sparc.cc | 67 |
2 files changed, 38 insertions, 35 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 534ff1d..c2daecd 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -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 diff --git a/gold/sparc.cc b/gold/sparc.cc index 9bca176..503cd8b 100644 --- a/gold/sparc.cc +++ b/gold/sparc.cc @@ -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; |