Révision | 549dba71045c856f3d169bf2edc7bfc7cabe5a0b (tree) |
---|---|
l'heure | 2015-12-07 11:47:00 |
Auteur | Alan Modra <amodra@gmai...> |
Commiter | Alan Modra |
[GOLD] R_PPC64_ENTRY support
elfcpp/
* powerpc.h (R_PPC64_ENTRY): Define.
gold/
* powerpc.cc (add_2_2_12, ld_2_12, lis_2): Define.
(Target_powerpc::Scan::local, global): Handle R_PPC64_ENTRY.
(Target_powerpc::Relocate::relocate): Edit code at R_PPC64_ENTRY.
@@ -1,3 +1,7 @@ | ||
1 | +2015-12-07 Alan Modra <amodra@gmail.com> | |
2 | + | |
3 | + * powerpc.h (R_PPC64_ENTRY): Define. | |
4 | + | |
1 | 5 | 2015-11-11 Alan Modra <amodra@gmail.com> |
2 | 6 | Peter Bergner <bergner@vnet.ibm.com> |
3 | 7 |
@@ -178,6 +178,7 @@ enum | ||
178 | 178 | R_PPC_EMB_RELSDA = 116, |
179 | 179 | R_PPC64_REL24_NOTOC = 116, |
180 | 180 | R_PPC64_ADDR64_LOCAL = 117, |
181 | + R_PPC64_ENTRY = 118, | |
181 | 182 | |
182 | 183 | R_PPC_VLE_REL8 = 216, |
183 | 184 | R_PPC_VLE_REL15 = 217, |
@@ -1,3 +1,9 @@ | ||
1 | +2015-12-07 Alan Modra <amodra@gmail.com> | |
2 | + | |
3 | + * powerpc.cc (add_2_2_12, ld_2_12, lis_2): Define. | |
4 | + (Target_powerpc::Scan::local, global): Handle R_PPC64_ENTRY. | |
5 | + (Target_powerpc::Relocate::relocate): Edit code at R_PPC64_ENTRY. | |
6 | + | |
1 | 7 | 2015-12-03 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com> |
2 | 8 | |
3 | 9 | * object.cc (Sized_relobj::do_for_all_local_got_entries): Use |
@@ -3224,6 +3224,7 @@ Output_data_plt_powerpc<size, big_endian>::add_local_ifunc_entry( | ||
3224 | 3224 | |
3225 | 3225 | static const uint32_t add_0_11_11 = 0x7c0b5a14; |
3226 | 3226 | static const uint32_t add_2_2_11 = 0x7c425a14; |
3227 | +static const uint32_t add_2_2_12 = 0x7c426214; | |
3227 | 3228 | static const uint32_t add_3_3_2 = 0x7c631214; |
3228 | 3229 | static const uint32_t add_3_3_13 = 0x7c636a14; |
3229 | 3230 | static const uint32_t add_11_0_11 = 0x7d605a14; |
@@ -3258,6 +3259,7 @@ static const uint32_t ld_0_12 = 0xe80c0000; | ||
3258 | 3259 | static const uint32_t ld_2_1 = 0xe8410000; |
3259 | 3260 | static const uint32_t ld_2_2 = 0xe8420000; |
3260 | 3261 | static const uint32_t ld_2_11 = 0xe84b0000; |
3262 | +static const uint32_t ld_2_12 = 0xe84c0000; | |
3261 | 3263 | static const uint32_t ld_11_2 = 0xe9620000; |
3262 | 3264 | static const uint32_t ld_11_11 = 0xe96b0000; |
3263 | 3265 | static const uint32_t ld_12_2 = 0xe9820000; |
@@ -3267,6 +3269,7 @@ static const uint32_t lfd_0_1 = 0xc8010000; | ||
3267 | 3269 | static const uint32_t li_0_0 = 0x38000000; |
3268 | 3270 | static const uint32_t li_12_0 = 0x39800000; |
3269 | 3271 | static const uint32_t lis_0 = 0x3c000000; |
3272 | +static const uint32_t lis_2 = 0x3c400000; | |
3270 | 3273 | static const uint32_t lis_11 = 0x3d600000; |
3271 | 3274 | static const uint32_t lis_12 = 0x3d800000; |
3272 | 3275 | static const uint32_t lvx_0_12_0 = 0x7c0c00ce; |
@@ -5607,6 +5610,7 @@ Target_powerpc<size, big_endian>::Scan::local( | ||
5607 | 5610 | case elfcpp::R_POWERPC_GNU_VTENTRY: |
5608 | 5611 | case elfcpp::R_PPC64_TOCSAVE: |
5609 | 5612 | case elfcpp::R_POWERPC_TLS: |
5613 | + case elfcpp::R_PPC64_ENTRY: | |
5610 | 5614 | break; |
5611 | 5615 | |
5612 | 5616 | case elfcpp::R_PPC64_TOC: |
@@ -5982,6 +5986,7 @@ Target_powerpc<size, big_endian>::Scan::global( | ||
5982 | 5986 | case elfcpp::R_POWERPC_GNU_VTENTRY: |
5983 | 5987 | case elfcpp::R_PPC_LOCAL24PC: |
5984 | 5988 | case elfcpp::R_POWERPC_TLS: |
5989 | + case elfcpp::R_PPC64_ENTRY: | |
5985 | 5990 | break; |
5986 | 5991 | |
5987 | 5992 | case elfcpp::R_PPC64_TOC: |
@@ -7655,6 +7660,48 @@ Target_powerpc<size, big_endian>::Relocate::relocate( | ||
7655 | 7660 | } |
7656 | 7661 | } |
7657 | 7662 | break; |
7663 | + | |
7664 | + case elfcpp::R_PPC64_ENTRY: | |
7665 | + value = (target->got_section()->output_section()->address() | |
7666 | + + object->toc_base_offset()); | |
7667 | + if (value + 0x80008000 <= 0xffffffff | |
7668 | + && !parameters->options().output_is_position_independent()) | |
7669 | + { | |
7670 | + Insn* iview = reinterpret_cast<Insn*>(view); | |
7671 | + Insn insn1 = elfcpp::Swap<32, big_endian>::readval(iview); | |
7672 | + Insn insn2 = elfcpp::Swap<32, big_endian>::readval(iview + 1); | |
7673 | + | |
7674 | + if ((insn1 & ~0xfffc) == ld_2_12 | |
7675 | + && insn2 == add_2_2_12) | |
7676 | + { | |
7677 | + insn1 = lis_2 + ha(value); | |
7678 | + elfcpp::Swap<32, big_endian>::writeval(iview, insn1); | |
7679 | + insn2 = addi_2_2 + l(value); | |
7680 | + elfcpp::Swap<32, big_endian>::writeval(iview + 1, insn2); | |
7681 | + return true; | |
7682 | + } | |
7683 | + } | |
7684 | + else | |
7685 | + { | |
7686 | + value -= address; | |
7687 | + if (value + 0x80008000 <= 0xffffffff) | |
7688 | + { | |
7689 | + Insn* iview = reinterpret_cast<Insn*>(view); | |
7690 | + Insn insn1 = elfcpp::Swap<32, big_endian>::readval(iview); | |
7691 | + Insn insn2 = elfcpp::Swap<32, big_endian>::readval(iview + 1); | |
7692 | + | |
7693 | + if ((insn1 & ~0xfffc) == ld_2_12 | |
7694 | + && insn2 == add_2_2_12) | |
7695 | + { | |
7696 | + insn1 = addis_2_12 + ha(value); | |
7697 | + elfcpp::Swap<32, big_endian>::writeval(iview, insn1); | |
7698 | + insn2 = addi_2_2 + l(value); | |
7699 | + elfcpp::Swap<32, big_endian>::writeval(iview + 1, insn2); | |
7700 | + return true; | |
7701 | + } | |
7702 | + } | |
7703 | + } | |
7704 | + break; | |
7658 | 7705 | } |
7659 | 7706 | } |
7660 | 7707 |