diff options
author | Cary Coutant <ccoutant@google.com> | 2015-01-14 10:30:14 -0800 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2015-01-14 10:30:14 -0800 |
commit | 3d0064a95d413e7d19ff9c7f6db53fefe44a697b (patch) | |
tree | 8e7a3d1e9d8c6490e7976627a5ca97697c3b26ea /gold | |
parent | cdf436294f7e0e3bd7668a81dfd5922fdd1aec14 (diff) | |
download | gdb-3d0064a95d413e7d19ff9c7f6db53fefe44a697b.zip gdb-3d0064a95d413e7d19ff9c7f6db53fefe44a697b.tar.gz gdb-3d0064a95d413e7d19ff9c7f6db53fefe44a697b.tar.bz2 |
Fix a bug in resolving HI16/LO16 relocation pairs for MIPS.
2015-01-14 Sasa Stankovic <Sasa.Stankovic@imgtec.com>
gold/
* mips.cc (reloc_high): Add r_sym.
(Mips_relocate_functions::relhi16): Add r_sym parameter. Pass r_sym to
reloc_high constructor.
(Mips_relocate_functions::relgot16_local): Likewise.
(Mips_relocate_functions::rello16): Add r_sym parameter. Use r_sym and
r_type to decide whether LO16 matches HI16.
(Target_mips::Relocate::relocate): Pass r_sym to calls to relhi16,
rello16 and relgot16_local.
Diffstat (limited to 'gold')
-rw-r--r-- | gold/ChangeLog | 11 | ||||
-rw-r--r-- | gold/mips.cc | 30 |
2 files changed, 28 insertions, 13 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 1e73aa8..9a52a3e 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,14 @@ +2015-01-14 Sasa Stankovic <Sasa.Stankovic@imgtec.com> + + * mips.cc (reloc_high): Add r_sym. + (Mips_relocate_functions::relhi16): Add r_sym parameter. Pass r_sym to + reloc_high constructor. + (Mips_relocate_functions::relgot16_local): Likewise. + (Mips_relocate_functions::rello16): Add r_sym parameter. Use r_sym and + r_type to decide whether LO16 matches HI16. + (Target_mips::Relocate::relocate): Pass r_sym to calls to relhi16, + rello16 and relgot16_local. + 2015-01-09 Cary Coutant <ccoutant@google.com> * layout.cc (Layout::set_segment_offsets): Don't align start of segment diff --git a/gold/mips.cc b/gold/mips.cc index 97cb492..acf76cf 100644 --- a/gold/mips.cc +++ b/gold/mips.cc @@ -3761,11 +3761,11 @@ struct reloc_high reloc_high(unsigned char* _view, const Mips_relobj<size, big_endian>* _object, const Symbol_value<size>* _psymval, Mips_address _addend, - unsigned int _r_type, bool _extract_addend, + unsigned int _r_type, unsigned int _r_sym, bool _extract_addend, Mips_address _address = 0, bool _gp_disp = false) : view(_view), object(_object), psymval(_psymval), addend(_addend), - r_type(_r_type), extract_addend(_extract_addend), address(_address), - gp_disp(_gp_disp) + r_type(_r_type), r_sym(_r_sym), extract_addend(_extract_addend), + address(_address), gp_disp(_gp_disp) { } unsigned char* view; @@ -3773,6 +3773,7 @@ struct reloc_high const Symbol_value<size>* psymval; Mips_address addend; unsigned int r_type; + unsigned int r_sym; bool extract_addend; Mips_address address; bool gp_disp; @@ -4266,11 +4267,12 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> relhi16(unsigned char* view, const Mips_relobj<size, big_endian>* object, const Symbol_value<size>* psymval, Mips_address addend, Mips_address address, bool gp_disp, unsigned int r_type, - bool extract_addend) + unsigned int r_sym, bool extract_addend) { // Record the relocation. It will be resolved when we find lo16 part. hi16_relocs.push_back(reloc_high<size, big_endian>(view, object, psymval, - addend, r_type, extract_addend, address, gp_disp)); + addend, r_type, r_sym, extract_addend, address, + gp_disp)); return This::STATUS_OKAY; } @@ -4331,11 +4333,11 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> relgot16_local(unsigned char* view, const Mips_relobj<size, big_endian>* object, const Symbol_value<size>* psymval, Mips_address addend_a, - bool extract_addend, unsigned int r_type) + bool extract_addend, unsigned int r_type, unsigned int r_sym) { // Record the relocation. It will be resolved when we find lo16 part. got16_relocs.push_back(reloc_high<size, big_endian>(view, object, psymval, - addend_a, r_type, extract_addend)); + addend_a, r_type, r_sym, extract_addend)); return This::STATUS_OKAY; } @@ -4377,7 +4379,7 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> const Mips_relobj<size, big_endian>* object, const Symbol_value<size>* psymval, Mips_address addend_a, bool extract_addend, Mips_address address, bool is_gp_disp, - unsigned int r_type) + unsigned int r_type, unsigned int r_sym) { mips_reloc_unshuffle(view, r_type, false); Valtype32* wv = reinterpret_cast<Valtype32*>(view); @@ -4392,7 +4394,8 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> while (it != hi16_relocs.end()) { reloc_high<size, big_endian> hi16 = *it; - if (hi16.psymval->value(hi16.object, 0) == psymval->value(object, 0)) + if (hi16.r_sym == r_sym + && is_matching_lo16_reloc(hi16.r_type, r_type)) { if (do_relhi16(hi16.view, hi16.object, hi16.psymval, hi16.addend, hi16.address, hi16.gp_disp, hi16.r_type, @@ -4411,7 +4414,8 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> while (it2 != got16_relocs.end()) { reloc_high<size, big_endian> got16 = *it2; - if (got16.psymval->value(got16.object, 0) == psymval->value(object, 0)) + if (got16.r_sym == r_sym + && is_matching_lo16_reloc(got16.r_type, r_type)) { if (do_relgot16_local(got16.view, got16.object, got16.psymval, got16.addend, got16.r_type, @@ -9908,7 +9912,7 @@ Target_mips<size, big_endian>::Relocate::relocate( case elfcpp::R_MIPS16_HI16: case elfcpp::R_MICROMIPS_HI16: reloc_status = Reloc_funcs::relhi16(view, object, psymval, r_addend, - address, gp_disp, r_type, + address, gp_disp, r_type, r_sym, extract_addend); break; @@ -9918,7 +9922,7 @@ Target_mips<size, big_endian>::Relocate::relocate( case elfcpp::R_MICROMIPS_HI0_LO16: reloc_status = Reloc_funcs::rello16(target, view, object, psymval, r_addend, extract_addend, address, - gp_disp, r_type); + gp_disp, r_type, r_sym); break; case elfcpp::R_MIPS_LITERAL: @@ -10033,7 +10037,7 @@ Target_mips<size, big_endian>::Relocate::relocate( else reloc_status = Reloc_funcs::relgot16_local(view, object, psymval, r_addend, extract_addend, - r_type); + r_type, r_sym); update_got_entry = changed_symbol_value; break; |