You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
6.4 KiB
173 lines
6.4 KiB
commit a078d95abc554b6c2572fcab5550591639b1c871 |
|
Author: Alan Modra <amodra@gmail.com> |
|
Date: Tue Oct 29 16:17:22 2013 +1030 |
|
|
|
Support ELFv2 stack frame. |
|
|
|
The toc pointer save slot changes on ELFv2 from 40(1) to 24(1). |
|
|
|
* elf64-ppc.c (STK_LR, STK_TOC, STK_LINKER): Define. |
|
(savegpr0_tail, restgpr0_tail, savefpr0_tail, restfpr0_tail) |
|
build_plt_stub, build_tls_get_addr_stub, ppc_build_one_stub, |
|
ppc64_elf_relocate_section): Use new defines. |
|
|
|
Index: gdb-7.6.1/bfd/elf64-ppc.c |
|
=================================================================== |
|
--- gdb-7.6.1.orig/bfd/elf64-ppc.c |
|
+++ gdb-7.6.1/bfd/elf64-ppc.c |
|
@@ -130,6 +130,14 @@ static bfd_vma opd_entry_value |
|
/* The initial size of the plt reserved for the dynamic linker. */ |
|
#define PLT_INITIAL_ENTRY_SIZE(htab) (htab->opd_abi ? 24 : 16) |
|
|
|
+/* Offsets to some stack save slots. */ |
|
+#define STK_LR 16 |
|
+#define STK_TOC(htab) (htab->opd_abi ? 40 : 24) |
|
+/* This one is dodgy. ABIv2 does not have a linker word, so use the |
|
+ CR save slot. Used only by optimised __tls_get_addr call stub, |
|
+ relying on __tls_get_addr_opt not saving CR.. */ |
|
+#define STK_LINKER(htab) (htab->opd_abi ? 32 : 8) |
|
+ |
|
/* TOC base pointers offset from start of TOC. */ |
|
#define TOC_BASE_OFF 0x8000 |
|
|
|
@@ -140,7 +148,7 @@ static bfd_vma opd_entry_value |
|
/* .plt call stub instructions. The normal stub is like this, but |
|
sometimes the .plt entry crosses a 64k boundary and we need to |
|
insert an addi to adjust r11. */ |
|
-#define STD_R2_40R1 0xf8410028 /* std %r2,40(%r1) */ |
|
+#define STD_R2_0R1 0xf8410000 /* std %r2,0+40(%r1) */ |
|
#define ADDIS_R11_R2 0x3d620000 /* addis %r11,%r2,xxx@ha */ |
|
#define LD_R12_0R11 0xe98b0000 /* ld %r12,xxx+0@l(%r11) */ |
|
#define MTCTR_R12 0x7d8903a6 /* mtctr %r12 */ |
|
@@ -164,7 +172,7 @@ static bfd_vma opd_entry_value |
|
#define LD_R11_0R2 0xe9620000 /* ld %r11,xxx+0(%r2) */ |
|
#define LD_R2_0R2 0xe8420000 /* ld %r2,xxx+0(%r2) */ |
|
|
|
-#define LD_R2_40R1 0xe8410028 /* ld %r2,40(%r1) */ |
|
+#define LD_R2_0R1 0xe8410000 /* ld %r2,0(%r1) */ |
|
|
|
/* glink call stub instructions. We enter with the index in R0. */ |
|
#define GLINK_CALL_STUB_SIZE (16*4) |
|
@@ -6326,7 +6334,7 @@ static bfd_byte * |
|
savegpr0_tail (bfd *abfd, bfd_byte *p, int r) |
|
{ |
|
p = savegpr0 (abfd, p, r); |
|
- bfd_put_32 (abfd, STD_R0_0R1 + 16, p); |
|
+ bfd_put_32 (abfd, STD_R0_0R1 + STK_LR, p); |
|
p = p + 4; |
|
bfd_put_32 (abfd, BLR, p); |
|
return p + 4; |
|
@@ -6342,7 +6350,7 @@ restgpr0 (bfd *abfd, bfd_byte *p, int r) |
|
static bfd_byte * |
|
restgpr0_tail (bfd *abfd, bfd_byte *p, int r) |
|
{ |
|
- bfd_put_32 (abfd, LD_R0_0R1 + 16, p); |
|
+ bfd_put_32 (abfd, LD_R0_0R1 + STK_LR, p); |
|
p = p + 4; |
|
p = restgpr0 (abfd, p, r); |
|
bfd_put_32 (abfd, MTLR_R0, p); |
|
@@ -6397,7 +6405,7 @@ static bfd_byte * |
|
savefpr0_tail (bfd *abfd, bfd_byte *p, int r) |
|
{ |
|
p = savefpr (abfd, p, r); |
|
- bfd_put_32 (abfd, STD_R0_0R1 + 16, p); |
|
+ bfd_put_32 (abfd, STD_R0_0R1 + STK_LR, p); |
|
p = p + 4; |
|
bfd_put_32 (abfd, BLR, p); |
|
return p + 4; |
|
@@ -6413,7 +6421,7 @@ restfpr (bfd *abfd, bfd_byte *p, int r) |
|
static bfd_byte * |
|
restfpr0_tail (bfd *abfd, bfd_byte *p, int r) |
|
{ |
|
- bfd_put_32 (abfd, LD_R0_0R1 + 16, p); |
|
+ bfd_put_32 (abfd, LD_R0_0R1 + STK_LR, p); |
|
p = p + 4; |
|
p = restfpr (abfd, p, r); |
|
bfd_put_32 (abfd, MTLR_R0, p); |
|
@@ -9873,7 +9881,7 @@ build_plt_stub (struct ppc_link_hash_tab |
|
} |
|
if (ALWAYS_EMIT_R2SAVE |
|
|| stub_entry->stub_type == ppc_stub_plt_call_r2save) |
|
- bfd_put_32 (obfd, STD_R2_40R1, p), p += 4; |
|
+ bfd_put_32 (obfd, STD_R2_0R1 + STK_TOC (htab), p), p += 4; |
|
bfd_put_32 (obfd, ADDIS_R11_R2 | PPC_HA (offset), p), p += 4; |
|
bfd_put_32 (obfd, LD_R12_0R11 | PPC_LO (offset), p), p += 4; |
|
if (plt_load_toc |
|
@@ -9927,7 +9935,7 @@ build_plt_stub (struct ppc_link_hash_tab |
|
} |
|
if (ALWAYS_EMIT_R2SAVE |
|
|| stub_entry->stub_type == ppc_stub_plt_call_r2save) |
|
- bfd_put_32 (obfd, STD_R2_40R1, p), p += 4; |
|
+ bfd_put_32 (obfd, STD_R2_0R1 + STK_TOC (htab), p), p += 4; |
|
bfd_put_32 (obfd, LD_R12_0R2 | PPC_LO (offset), p), p += 4; |
|
if (plt_load_toc |
|
&& PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset)) |
|
@@ -9968,11 +9976,9 @@ build_plt_stub (struct ppc_link_hash_tab |
|
#define ADD_R3_R12_R13 0x7c6c6a14 |
|
#define BEQLR 0x4d820020 |
|
#define MR_R3_R0 0x7c030378 |
|
-#define MFLR_R11 0x7d6802a6 |
|
#define STD_R11_0R1 0xf9610000 |
|
#define BCTRL 0x4e800421 |
|
#define LD_R11_0R1 0xe9610000 |
|
-#define LD_R2_0R1 0xe8410000 |
|
#define MTLR_R11 0x7d6803a6 |
|
|
|
static inline bfd_byte * |
|
@@ -9990,15 +9996,15 @@ build_tls_get_addr_stub (struct ppc_link |
|
bfd_put_32 (obfd, BEQLR, p), p += 4; |
|
bfd_put_32 (obfd, MR_R3_R0, p), p += 4; |
|
bfd_put_32 (obfd, MFLR_R11, p), p += 4; |
|
- bfd_put_32 (obfd, STD_R11_0R1 + 32, p), p += 4; |
|
+ bfd_put_32 (obfd, STD_R11_0R1 + STK_LINKER (htab), p), p += 4; |
|
|
|
if (r != NULL) |
|
r[0].r_offset += 9 * 4; |
|
p = build_plt_stub (htab, stub_entry, p, offset, r); |
|
bfd_put_32 (obfd, BCTRL, p - 4); |
|
|
|
- bfd_put_32 (obfd, LD_R11_0R1 + 32, p), p += 4; |
|
- bfd_put_32 (obfd, LD_R2_0R1 + 40, p), p += 4; |
|
+ bfd_put_32 (obfd, LD_R11_0R1 + STK_LINKER (htab), p), p += 4; |
|
+ bfd_put_32 (obfd, LD_R2_0R1 + STK_TOC (htab), p), p += 4; |
|
bfd_put_32 (obfd, MTLR_R11, p), p += 4; |
|
bfd_put_32 (obfd, BLR, p), p += 4; |
|
|
|
@@ -10122,7 +10128,7 @@ ppc_build_one_stub (struct bfd_hash_entr |
|
htab->stub_error = TRUE; |
|
return FALSE; |
|
} |
|
- bfd_put_32 (htab->stub_bfd, STD_R2_40R1, loc); |
|
+ bfd_put_32 (htab->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc); |
|
loc += 4; |
|
size = 12; |
|
if (PPC_HA (r2off) != 0) |
|
@@ -10318,7 +10324,7 @@ ppc_build_one_stub (struct bfd_hash_entr |
|
return FALSE; |
|
} |
|
|
|
- bfd_put_32 (htab->stub_bfd, STD_R2_40R1, loc); |
|
+ bfd_put_32 (htab->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc); |
|
loc += 4; |
|
size = 20; |
|
if (PPC_HA (off) != 0) |
|
@@ -13113,7 +13119,8 @@ ppc64_elf_relocate_section (bfd *output_ |
|
insn = bfd_get_32 (input_bfd, contents + rel->r_offset); |
|
if (insn == NOP |
|
|| insn == CROR_151515 || insn == CROR_313131) |
|
- bfd_put_32 (input_bfd, STD_R2_40R1, |
|
+ bfd_put_32 (input_bfd, |
|
+ STD_R2_0R1 + STK_TOC (htab), |
|
contents + rel->r_offset); |
|
} |
|
break; |
|
@@ -13172,7 +13179,8 @@ ppc64_elf_relocate_section (bfd *output_ |
|
/* Special stub used, leave nop alone. */ |
|
} |
|
else |
|
- bfd_put_32 (input_bfd, LD_R2_40R1, |
|
+ bfd_put_32 (input_bfd, |
|
+ LD_R2_0R1 + STK_TOC (htab), |
|
contents + rel->r_offset + 4); |
|
can_plt_call = TRUE; |
|
}
|
|
|