diff options
author | Cary Coutant <ccoutant@gmail.com> | 2017-11-27 17:32:55 -0800 |
---|---|---|
committer | Cary Coutant <ccoutant@gmail.com> | 2017-11-27 17:32:55 -0800 |
commit | 033bfb739b525703bfe23f151d09e9beee3a2afe (patch) | |
tree | ab65b33cf7f56e20ac65ab3063e6053110abff12 /gold/target-reloc.h | |
parent | 57c1b6811a2d97a3de229351ed19201853245a5d (diff) | |
download | gdb-033bfb739b525703bfe23f151d09e9beee3a2afe.zip gdb-033bfb739b525703bfe23f151d09e9beee3a2afe.tar.gz gdb-033bfb739b525703bfe23f151d09e9beee3a2afe.tar.bz2 |
Fix symbol values and relocation addends for relocatable links.
The fix for PR 19291 broke some other cases where -r is used with scripts,
as reported in PR 22266. The original fix for PR 22266 ended up breaking
many cases for REL targets, where the addends are stored in the section data,
and are not being adjusted properly.
The problem was basically that in a relocatable output file (ET_REL),
symbol values are supposed to be relative to the start address of their
section. Usually in a relocatable file, all sections start at 0, so the
failure to get this right is often irrelevant, but with a linker script,
we occasionally see an output section whose starting address is not 0,
and gold would occasionally write a symbol with its relocated value instead
of its section-relative value.
This patch reverts the recent fix for PR 22266 as well as my original fix
for PR 19291. The original fix moved the symbol value adjustment to
write_local_symbols, but neglected to undo a few places where the adjustment
was also being applied, resulting in an occasional double adjustment. The
more recent fix removed those other adjustments, but then failed to
re-account for the adjustment when rewriting the relocations on REL targets.
With the old attempts reverted, we now apply the symbol value adjustment to
the one case that had been missed (non-section symbols in merge sections).
But now we also need to account for the adjustment when rewriting the addends
for RELA relocations.
gold/
PR gold/19291
PR gold/22266
* object.cc (Sized_relobj_file::compute_final_local_value_internal):
Revert changes from 2017-11-08 patch. Adjust symbol value in
relocatable links for non-section symbols.
(Sized_relobj_file::compute_final_local_value): Revert changes from
2017-11-08 patch.
(Sized_relobj_file::do_finalize_local_symbols): Likewise.
(Sized_relobj_file::write_local_symbols): Revert changes from
2015-11-25 patch.
* object.h (Sized_relobj_file::compute_final_local_value_internal):
Revert changes from 2017-11-08 patch.
* powerpc.cc (Target_powerpc::relocate_relocs): Adjust addend for
relocatable links.
* target-reloc.h (relocate_relocs): Adjust addend for relocatable links.
* testsuite/pr22266_a.c (hello): New function.
* testsuite/pr22266_main.c (main): Add test for merge sections.
* testsuite/pr22266_script.t: Add rule for .rodata.
Diffstat (limited to 'gold/target-reloc.h')
-rw-r--r-- | gold/target-reloc.h | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/gold/target-reloc.h b/gold/target-reloc.h index c8b86c6..79ed1d3 100644 --- a/gold/target-reloc.h +++ b/gold/target-reloc.h @@ -755,6 +755,8 @@ relocate_relocs( unsigned char* pwrite = reloc_view; + const bool relocatable = parameters->options().relocatable(); + for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size) { Relocatable_relocs::Reloc_strategy strategy = relinfo->rr->strategy(i); @@ -857,7 +859,7 @@ relocate_relocs( // In an object file, r_offset is an offset within the section. // In an executable or dynamic object, generated by // --emit-relocs, r_offset is an absolute address. - if (!parameters->options().relocatable()) + if (!relocatable) { new_offset += view_address; if (offset_in_output_section != invalid_address) @@ -892,10 +894,17 @@ relocate_relocs( { case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA: { - typename elfcpp::Elf_types<size>::Elf_Swxword addend; - addend = Classify_reloc::get_r_addend(&reloc); - gold_assert(os != NULL); - addend = psymval->value(object, addend) - os->address(); + typename elfcpp::Elf_types<size>::Elf_Swxword addend + = Classify_reloc::get_r_addend(&reloc); + addend = psymval->value(object, addend); + // In a relocatable link, the symbol value is relative to + // the start of the output section. For a non-relocatable + // link, we need to adjust the addend. + if (!relocatable) + { + gold_assert(os != NULL); + addend -= os->address(); + } Classify_reloc::put_r_addend(&reloc_write, addend); } break; |