Adjust local symbol value in relocatable link to be relative to section.
authorCary Coutant <ccoutant@gmail.com>
Wed, 25 Nov 2015 16:50:41 +0000 (08:50 -0800)
committerCary Coutant <ccoutant@gmail.com>
Wed, 25 Nov 2015 16:50:41 +0000 (08:50 -0800)
gold/
PR gold/19291
* object.cc (Sized_relobj_file::write_local_symbols): If relocatable,
subtract section address from symbol value.

gold/ChangeLog
gold/object.cc

index a07226102b88996070a658e049ccc335e11efa24..5eefa29eac9b1a86e07978de50438eb2a53891c9 100644 (file)
@@ -1,3 +1,9 @@
+2015-11-25  Cary Coutant  <ccoutant@gmail.com>
+
+       PR gold/19291
+       * object.cc (Sized_relobj_file::write_local_symbols): If relocatable,
+       subtract section address from symbol value.
+
 2015-11-25  Alan Modra  <amodra@gmail.com>
 
        * powerpc.cc (Output_data_got_powerpc::Output_data_got_powerpc): Align
index 76d4630d16a8cfbe445f421250798c3438aa48e4..5381addde717f98c9eb4d1fc8ccdd00b1e89afe2 100644 (file)
@@ -2674,6 +2674,7 @@ Sized_relobj_file<size, big_endian>::write_local_symbols(
       elfcpp::Sym<size, big_endian> isym(psyms);
 
       Symbol_value<size>& lv(this->local_values_[i]);
+      typename elfcpp::Elf_types<size>::Elf_Addr sym_value = lv.value(this, 0);
 
       bool is_ordinary;
       unsigned int st_shndx = this->adjust_sym_shndx(i, isym.get_st_shndx(),
@@ -2683,6 +2684,9 @@ Sized_relobj_file<size, big_endian>::write_local_symbols(
          gold_assert(st_shndx < out_sections.size());
          if (out_sections[st_shndx] == NULL)
            continue;
+         // In relocatable object files symbol values are section relative.
+         if (parameters->options().relocatable())
+           sym_value -= out_sections[st_shndx]->address();
          st_shndx = out_sections[st_shndx]->out_shndx();
          if (st_shndx >= elfcpp::SHN_LORESERVE)
            {
@@ -2702,7 +2706,7 @@ Sized_relobj_file<size, big_endian>::write_local_symbols(
          gold_assert(isym.get_st_name() < strtab_size);
          const char* name = pnames + isym.get_st_name();
          osym.put_st_name(sympool->get_offset(name));
-         osym.put_st_value(this->local_values_[i].value(this, 0));
+         osym.put_st_value(sym_value);
          osym.put_st_size(isym.get_st_size());
          osym.put_st_info(isym.get_st_info());
          osym.put_st_other(isym.get_st_other());
@@ -2720,7 +2724,7 @@ Sized_relobj_file<size, big_endian>::write_local_symbols(
          gold_assert(isym.get_st_name() < strtab_size);
          const char* name = pnames + isym.get_st_name();
          osym.put_st_name(dynpool->get_offset(name));
-         osym.put_st_value(this->local_values_[i].value(this, 0));
+         osym.put_st_value(sym_value);
          osym.put_st_size(isym.get_st_size());
          osym.put_st_info(isym.get_st_info());
          osym.put_st_other(isym.get_st_other());