|
|
881b8e |
2014-03-12 Aldy Hernandez <aldyh@redhat.com>
|
|
|
881b8e |
|
|
|
881b8e |
* Partial PowerPC little endian patch for binutils.
|
|
|
881b8e |
|
|
|
881b8e |
diff --git a/IBM-binutils-2.24-2013-11-11-ppc64le_abiv2.patch.gz b/IBM-binutils-2.24-2013-11-11-ppc64le_abiv2.patch.gz
|
|
|
881b8e |
new file mode 100644
|
|
|
881b8e |
index 0000000..e869701
|
|
|
881b8e |
Binary files /dev/null and b/IBM-binutils-2.24-2013-11-11-ppc64le_abiv2.patch.gz differ
|
|
|
881b8e |
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
|
|
|
881b8e |
index 8c9903f..af72703 100644
|
|
|
881b8e |
--- a/bfd/bfd-in2.h
|
|
|
881b8e |
+++ b/bfd/bfd-in2.h
|
|
|
881b8e |
@@ -3189,6 +3189,8 @@ instruction. */
|
|
|
881b8e |
BFD_RELOC_PPC64_TOC16_LO_DS,
|
|
|
881b8e |
BFD_RELOC_PPC64_PLTGOT16_DS,
|
|
|
881b8e |
BFD_RELOC_PPC64_PLTGOT16_LO_DS,
|
|
|
881b8e |
+ BFD_RELOC_PPC64_ADDR16_HIGH,
|
|
|
881b8e |
+ BFD_RELOC_PPC64_ADDR16_HIGHA,
|
|
|
881b8e |
|
|
|
881b8e |
/* PowerPC and PowerPC64 thread-local storage relocations. */
|
|
|
881b8e |
BFD_RELOC_PPC_TLS,
|
|
|
881b8e |
@@ -3233,6 +3235,10 @@ instruction. */
|
|
|
881b8e |
BFD_RELOC_PPC64_DTPREL16_HIGHERA,
|
|
|
881b8e |
BFD_RELOC_PPC64_DTPREL16_HIGHEST,
|
|
|
881b8e |
BFD_RELOC_PPC64_DTPREL16_HIGHESTA,
|
|
|
881b8e |
+ BFD_RELOC_PPC64_TPREL16_HIGH,
|
|
|
881b8e |
+ BFD_RELOC_PPC64_TPREL16_HIGHA,
|
|
|
881b8e |
+ BFD_RELOC_PPC64_DTPREL16_HIGH,
|
|
|
881b8e |
+ BFD_RELOC_PPC64_DTPREL16_HIGHA,
|
|
|
881b8e |
|
|
|
881b8e |
/* IBM 370/390 relocations */
|
|
|
881b8e |
BFD_RELOC_I370_D12,
|
|
|
881b8e |
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
|
|
|
881b8e |
index fbc4e54..a3680f2 100644
|
|
|
881b8e |
--- a/bfd/elf32-ppc.c
|
|
|
881b8e |
+++ b/bfd/elf32-ppc.c
|
|
|
881b8e |
@@ -6443,7 +6443,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
881b8e |
if (!htab->no_tls_get_addr_opt
|
|
|
881b8e |
&& htab->tls_get_addr != NULL
|
|
|
881b8e |
&& htab->tls_get_addr->plt.plist != NULL
|
|
|
881b8e |
- && !add_dynamic_entry (DT_PPC_TLSOPT, 0))
|
|
|
881b8e |
+ && !add_dynamic_entry (DT_PPC_OPT, PPC_OPT_TLS))
|
|
|
881b8e |
return FALSE;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
|
|
|
881b8e |
index 8872673..80c2a4d 100644
|
|
|
881b8e |
--- a/bfd/elf64-ppc.c
|
|
|
881b8e |
+++ b/bfd/elf64-ppc.c
|
|
|
881b8e |
@@ -81,7 +81,8 @@ static bfd_vma opd_entry_value
|
|
|
881b8e |
#define bfd_elf64_mkobject ppc64_elf_mkobject
|
|
|
881b8e |
#define bfd_elf64_bfd_reloc_type_lookup ppc64_elf_reloc_type_lookup
|
|
|
881b8e |
#define bfd_elf64_bfd_reloc_name_lookup ppc64_elf_reloc_name_lookup
|
|
|
881b8e |
-#define bfd_elf64_bfd_merge_private_bfd_data _bfd_generic_verify_endian_match
|
|
|
881b8e |
+#define bfd_elf64_bfd_merge_private_bfd_data ppc64_elf_merge_private_bfd_data
|
|
|
881b8e |
+#define bfd_elf64_bfd_print_private_bfd_data ppc64_elf_print_private_bfd_data
|
|
|
881b8e |
#define bfd_elf64_new_section_hook ppc64_elf_new_section_hook
|
|
|
881b8e |
#define bfd_elf64_bfd_link_hash_table_create ppc64_elf_link_hash_table_create
|
|
|
881b8e |
#define bfd_elf64_bfd_link_hash_table_free ppc64_elf_link_hash_table_free
|
|
|
881b8e |
@@ -108,6 +109,7 @@ static bfd_vma opd_entry_value
|
|
|
881b8e |
#define elf_backend_maybe_function_sym ppc64_elf_maybe_function_sym
|
|
|
881b8e |
#define elf_backend_always_size_sections ppc64_elf_func_desc_adjust
|
|
|
881b8e |
#define elf_backend_size_dynamic_sections ppc64_elf_size_dynamic_sections
|
|
|
881b8e |
+#define elf_backend_hash_symbol ppc64_elf_hash_symbol
|
|
|
881b8e |
#define elf_backend_init_index_section _bfd_elf_init_2_index_sections
|
|
|
881b8e |
#define elf_backend_action_discarded ppc64_elf_action_discarded
|
|
|
881b8e |
#define elf_backend_relocate_section ppc64_elf_relocate_section
|
|
|
881b8e |
@@ -117,16 +119,25 @@ static bfd_vma opd_entry_value
|
|
|
881b8e |
#define elf_backend_link_output_symbol_hook ppc64_elf_output_symbol_hook
|
|
|
881b8e |
#define elf_backend_special_sections ppc64_elf_special_sections
|
|
|
881b8e |
#define elf_backend_post_process_headers _bfd_elf_set_osabi
|
|
|
881b8e |
+#define elf_backend_merge_symbol_attribute ppc64_elf_merge_symbol_attribute
|
|
|
881b8e |
|
|
|
881b8e |
/* The name of the dynamic interpreter. This is put in the .interp
|
|
|
881b8e |
section. */
|
|
|
881b8e |
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
|
|
|
881b8e |
|
|
|
881b8e |
/* The size in bytes of an entry in the procedure linkage table. */
|
|
|
881b8e |
-#define PLT_ENTRY_SIZE 24
|
|
|
881b8e |
+#define PLT_ENTRY_SIZE(htab) (htab->opd_abi ? 24 : 8)
|
|
|
881b8e |
|
|
|
881b8e |
/* The initial size of the plt reserved for the dynamic linker. */
|
|
|
881b8e |
-#define PLT_INITIAL_ENTRY_SIZE PLT_ENTRY_SIZE
|
|
|
881b8e |
+#define PLT_INITIAL_ENTRY_SIZE(htab) (htab->opd_abi ? 24 : 16)
|
|
|
881b8e |
+
|
|
|
881b8e |
+/* Offsets to some stack save slots. */
|
|
|
881b8e |
+#define STK_LR 16
|
|
|
881b8e |
+#define STK_TOC(htab) (htab->opd_abi ? 40 : 24)
|
|
|
881b8e |
+/* This one is dodgy. ABIv2 does not have a linker word, so use the
|
|
|
881b8e |
+ CR save slot. Used only by optimised __tls_get_addr call stub,
|
|
|
881b8e |
+ relying on __tls_get_addr_opt not saving CR.. */
|
|
|
881b8e |
+#define STK_LINKER(htab) (htab->opd_abi ? 32 : 8)
|
|
|
881b8e |
|
|
|
881b8e |
/* TOC base pointers offset from start of TOC. */
|
|
|
881b8e |
#define TOC_BASE_OFF 0x8000
|
|
|
881b8e |
@@ -137,33 +148,35 @@ static bfd_vma opd_entry_value
|
|
|
881b8e |
|
|
|
881b8e |
/* .plt call stub instructions. The normal stub is like this, but
|
|
|
881b8e |
sometimes the .plt entry crosses a 64k boundary and we need to
|
|
|
881b8e |
- insert an addi to adjust r12. */
|
|
|
881b8e |
-#define PLT_CALL_STUB_SIZE (7*4)
|
|
|
881b8e |
-#define ADDIS_R12_R2 0x3d820000 /* addis %r12,%r2,xxx@ha */
|
|
|
881b8e |
-#define STD_R2_40R1 0xf8410028 /* std %r2,40(%r1) */
|
|
|
881b8e |
-#define LD_R11_0R12 0xe96c0000 /* ld %r11,xxx+0@l(%r12) */
|
|
|
881b8e |
-#define MTCTR_R11 0x7d6903a6 /* mtctr %r11 */
|
|
|
881b8e |
-#define LD_R2_0R12 0xe84c0000 /* ld %r2,xxx+8@l(%r12) */
|
|
|
881b8e |
- /* ld %r11,xxx+16@l(%r12) */
|
|
|
881b8e |
+ insert an addi to adjust r11. */
|
|
|
881b8e |
+#define STD_R2_0R1 0xf8410000 /* std %r2,0+40(%r1) */
|
|
|
881b8e |
+#define ADDIS_R11_R2 0x3d620000 /* addis %r11,%r2,xxx@ha */
|
|
|
881b8e |
+#define LD_R12_0R11 0xe98b0000 /* ld %r12,xxx+0@l(%r11) */
|
|
|
881b8e |
+#define MTCTR_R12 0x7d8903a6 /* mtctr %r12 */
|
|
|
881b8e |
+#define LD_R2_0R11 0xe84b0000 /* ld %r2,xxx+8@l(%r11) */
|
|
|
881b8e |
+#define LD_R11_0R11 0xe96b0000 /* ld %r11,xxx+16@l(%r11) */
|
|
|
881b8e |
#define BCTR 0x4e800420 /* bctr */
|
|
|
881b8e |
|
|
|
881b8e |
-
|
|
|
881b8e |
-#define ADDIS_R12_R12 0x3d8c0000 /* addis %r12,%r12,off@ha */
|
|
|
881b8e |
-#define ADDI_R12_R12 0x398c0000 /* addi %r12,%r12,off@l */
|
|
|
881b8e |
+#define ADDI_R11_R11 0x396b0000 /* addi %r11,%r11,off@l */
|
|
|
881b8e |
#define ADDIS_R2_R2 0x3c420000 /* addis %r2,%r2,off@ha */
|
|
|
881b8e |
#define ADDI_R2_R2 0x38420000 /* addi %r2,%r2,off@l */
|
|
|
881b8e |
|
|
|
881b8e |
-#define XOR_R11_R11_R11 0x7d6b5a78 /* xor %r11,%r11,%r11 */
|
|
|
881b8e |
-#define ADD_R12_R12_R11 0x7d8c5a14 /* add %r12,%r12,%r11 */
|
|
|
881b8e |
+#define XOR_R2_R12_R12 0x7d826278 /* xor %r2,%r12,%r12 */
|
|
|
881b8e |
+#define ADD_R11_R11_R2 0x7d6b1214 /* add %r11,%r11,%r2 */
|
|
|
881b8e |
+#define XOR_R11_R12_R12 0x7d8b6278 /* xor %r11,%r12,%r12 */
|
|
|
881b8e |
#define ADD_R2_R2_R11 0x7c425a14 /* add %r2,%r2,%r11 */
|
|
|
881b8e |
#define CMPLDI_R2_0 0x28220000 /* cmpldi %r2,0 */
|
|
|
881b8e |
#define BNECTR 0x4ca20420 /* bnectr+ */
|
|
|
881b8e |
#define BNECTR_P4 0x4ce20420 /* bnectr+ */
|
|
|
881b8e |
|
|
|
881b8e |
+#define LD_R12_0R2 0xe9820000 /* ld %r12,xxx+0(%r2) */
|
|
|
881b8e |
#define LD_R11_0R2 0xe9620000 /* ld %r11,xxx+0(%r2) */
|
|
|
881b8e |
#define LD_R2_0R2 0xe8420000 /* ld %r2,xxx+0(%r2) */
|
|
|
881b8e |
|
|
|
881b8e |
-#define LD_R2_40R1 0xe8410028 /* ld %r2,40(%r1) */
|
|
|
881b8e |
+#define LD_R2_0R1 0xe8410000 /* ld %r2,0(%r1) */
|
|
|
881b8e |
+
|
|
|
881b8e |
+#define ADDIS_R12_R12 0x3d8c0000 /* addis %r12,%r12,xxx@ha */
|
|
|
881b8e |
+#define LD_R12_0R12 0xe98c0000 /* ld %r12,xxx@l(%r12) */
|
|
|
881b8e |
|
|
|
881b8e |
/* glink call stub instructions. We enter with the index in R0. */
|
|
|
881b8e |
#define GLINK_CALL_STUB_SIZE (16*4)
|
|
|
881b8e |
@@ -174,14 +187,19 @@ static bfd_vma opd_entry_value
|
|
|
881b8e |
#define BCL_20_31 0x429f0005 /* bcl 20,31,1f */
|
|
|
881b8e |
/* 1: */
|
|
|
881b8e |
#define MFLR_R11 0x7d6802a6 /* mflr %11 */
|
|
|
881b8e |
-#define LD_R2_M16R11 0xe84bfff0 /* ld %2,(0b-1b)(%11) */
|
|
|
881b8e |
+ /* ld %2,(0b-1b)(%11) */
|
|
|
881b8e |
#define MTLR_R12 0x7d8803a6 /* mtlr %12 */
|
|
|
881b8e |
-#define ADD_R12_R2_R11 0x7d825a14 /* add %12,%2,%11 */
|
|
|
881b8e |
- /* ld %11,0(%12) */
|
|
|
881b8e |
- /* ld %2,8(%12) */
|
|
|
881b8e |
- /* mtctr %11 */
|
|
|
881b8e |
- /* ld %11,16(%12) */
|
|
|
881b8e |
+#define ADD_R11_R2_R11 0x7d625a14 /* add %11,%2,%11 */
|
|
|
881b8e |
+ /* ld %12,0(%11) */
|
|
|
881b8e |
+ /* ld %2,8(%11) */
|
|
|
881b8e |
+ /* mtctr %12 */
|
|
|
881b8e |
+ /* ld %11,16(%11) */
|
|
|
881b8e |
/* bctr */
|
|
|
881b8e |
+#define MFLR_R0 0x7c0802a6 /* mflr %r0 */
|
|
|
881b8e |
+#define MTLR_R0 0x7c0803a6 /* mtlr %r0 */
|
|
|
881b8e |
+#define SUB_R12_R12_R11 0x7d8b6050 /* subf %r12,%r11,%r12 */
|
|
|
881b8e |
+#define ADDI_R0_R12 0x380c0000 /* addi %r0,%r12,0 */
|
|
|
881b8e |
+#define SRDI_R0_R0_2 0x7800f082 /* rldicl %r0,%r0,62,2 */
|
|
|
881b8e |
|
|
|
881b8e |
/* Pad with this. */
|
|
|
881b8e |
#define NOP 0x60000000
|
|
|
881b8e |
@@ -309,7 +327,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
bfd_elf_generic_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_ADDR16_HI", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -325,7 +343,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_ha_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_ADDR16_HA", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -487,7 +505,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont,/* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed,/* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_GOT16_HI", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -503,7 +521,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont,/* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed,/* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_GOT16_HA", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -680,7 +698,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_PLT16_HI", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -696,7 +714,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_PLT16_HA", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -741,7 +759,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_sectoff_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_SECTOFF_HI", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -756,7 +774,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_sectoff_ha_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_SECTOFF_HA", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -963,7 +981,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_toc_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_TOC16_HI", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -982,7 +1000,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_toc_ha_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_TOC16_HA", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1054,7 +1072,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_PLTGOT16_HI", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1072,7 +1090,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont,/* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_PLTGOT16_HA", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1374,7 +1392,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_DTPREL16_HI", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1389,7 +1407,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_DTPREL16_HA", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1540,7 +1558,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_TPREL16_HI", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1555,7 +1573,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_TPREL16_HA", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1692,7 +1710,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_GOT_TLSGD16_HI", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1707,7 +1725,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_GOT_TLSGD16_HA", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1754,7 +1772,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_GOT_TLSLD16_HI", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1769,7 +1787,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_GOT_TLSLD16_HA", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1815,7 +1833,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_GOT_DTPREL16_HI", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1830,7 +1848,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_GOT_DTPREL16_HA", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1876,7 +1894,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_GOT_TPREL16_HI", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1891,7 +1909,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
FALSE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_GOT_TPREL16_HA", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1964,7 +1982,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
TRUE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
bfd_elf_generic_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_REL16_HI", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1980,7 +1998,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
16, /* bitsize */
|
|
|
881b8e |
TRUE, /* pc_relative */
|
|
|
881b8e |
0, /* bitpos */
|
|
|
881b8e |
- complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ complain_overflow_signed, /* complain_on_overflow */
|
|
|
881b8e |
ppc64_elf_ha_reloc, /* special_function */
|
|
|
881b8e |
"R_PPC64_REL16_HA", /* name */
|
|
|
881b8e |
FALSE, /* partial_inplace */
|
|
|
881b8e |
@@ -1988,6 +2006,96 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|
|
881b8e |
0xffff, /* dst_mask */
|
|
|
881b8e |
TRUE), /* pcrel_offset */
|
|
|
881b8e |
|
|
|
881b8e |
+ /* Like R_PPC64_ADDR16_HI, but no overflow. */
|
|
|
881b8e |
+ HOWTO (R_PPC64_ADDR16_HIGH, /* type */
|
|
|
881b8e |
+ 16, /* rightshift */
|
|
|
881b8e |
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
|
|
881b8e |
+ 16, /* bitsize */
|
|
|
881b8e |
+ FALSE, /* pc_relative */
|
|
|
881b8e |
+ 0, /* bitpos */
|
|
|
881b8e |
+ complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ bfd_elf_generic_reloc, /* special_function */
|
|
|
881b8e |
+ "R_PPC64_ADDR16_HIGH", /* name */
|
|
|
881b8e |
+ FALSE, /* partial_inplace */
|
|
|
881b8e |
+ 0, /* src_mask */
|
|
|
881b8e |
+ 0xffff, /* dst_mask */
|
|
|
881b8e |
+ FALSE), /* pcrel_offset */
|
|
|
881b8e |
+
|
|
|
881b8e |
+ /* Like R_PPC64_ADDR16_HA, but no overflow. */
|
|
|
881b8e |
+ HOWTO (R_PPC64_ADDR16_HIGHA, /* type */
|
|
|
881b8e |
+ 16, /* rightshift */
|
|
|
881b8e |
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
|
|
881b8e |
+ 16, /* bitsize */
|
|
|
881b8e |
+ FALSE, /* pc_relative */
|
|
|
881b8e |
+ 0, /* bitpos */
|
|
|
881b8e |
+ complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ ppc64_elf_ha_reloc, /* special_function */
|
|
|
881b8e |
+ "R_PPC64_ADDR16_HIGHA", /* name */
|
|
|
881b8e |
+ FALSE, /* partial_inplace */
|
|
|
881b8e |
+ 0, /* src_mask */
|
|
|
881b8e |
+ 0xffff, /* dst_mask */
|
|
|
881b8e |
+ FALSE), /* pcrel_offset */
|
|
|
881b8e |
+
|
|
|
881b8e |
+ /* Like R_PPC64_DTPREL16_HI, but no overflow. */
|
|
|
881b8e |
+ HOWTO (R_PPC64_DTPREL16_HIGH,
|
|
|
881b8e |
+ 16, /* rightshift */
|
|
|
881b8e |
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
|
|
881b8e |
+ 16, /* bitsize */
|
|
|
881b8e |
+ FALSE, /* pc_relative */
|
|
|
881b8e |
+ 0, /* bitpos */
|
|
|
881b8e |
+ complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
+ "R_PPC64_DTPREL16_HIGH", /* name */
|
|
|
881b8e |
+ FALSE, /* partial_inplace */
|
|
|
881b8e |
+ 0, /* src_mask */
|
|
|
881b8e |
+ 0xffff, /* dst_mask */
|
|
|
881b8e |
+ FALSE), /* pcrel_offset */
|
|
|
881b8e |
+
|
|
|
881b8e |
+ /* Like R_PPC64_DTPREL16_HA, but no overflow. */
|
|
|
881b8e |
+ HOWTO (R_PPC64_DTPREL16_HIGHA,
|
|
|
881b8e |
+ 16, /* rightshift */
|
|
|
881b8e |
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
|
|
881b8e |
+ 16, /* bitsize */
|
|
|
881b8e |
+ FALSE, /* pc_relative */
|
|
|
881b8e |
+ 0, /* bitpos */
|
|
|
881b8e |
+ complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
+ "R_PPC64_DTPREL16_HIGHA", /* name */
|
|
|
881b8e |
+ FALSE, /* partial_inplace */
|
|
|
881b8e |
+ 0, /* src_mask */
|
|
|
881b8e |
+ 0xffff, /* dst_mask */
|
|
|
881b8e |
+ FALSE), /* pcrel_offset */
|
|
|
881b8e |
+
|
|
|
881b8e |
+ /* Like R_PPC64_TPREL16_HI, but no overflow. */
|
|
|
881b8e |
+ HOWTO (R_PPC64_TPREL16_HIGH,
|
|
|
881b8e |
+ 16, /* rightshift */
|
|
|
881b8e |
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
|
|
881b8e |
+ 16, /* bitsize */
|
|
|
881b8e |
+ FALSE, /* pc_relative */
|
|
|
881b8e |
+ 0, /* bitpos */
|
|
|
881b8e |
+ complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
+ "R_PPC64_TPREL16_HIGH", /* name */
|
|
|
881b8e |
+ FALSE, /* partial_inplace */
|
|
|
881b8e |
+ 0, /* src_mask */
|
|
|
881b8e |
+ 0xffff, /* dst_mask */
|
|
|
881b8e |
+ FALSE), /* pcrel_offset */
|
|
|
881b8e |
+
|
|
|
881b8e |
+ /* Like R_PPC64_TPREL16_HA, but no overflow. */
|
|
|
881b8e |
+ HOWTO (R_PPC64_TPREL16_HIGHA,
|
|
|
881b8e |
+ 16, /* rightshift */
|
|
|
881b8e |
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
|
|
881b8e |
+ 16, /* bitsize */
|
|
|
881b8e |
+ FALSE, /* pc_relative */
|
|
|
881b8e |
+ 0, /* bitpos */
|
|
|
881b8e |
+ complain_overflow_dont, /* complain_on_overflow */
|
|
|
881b8e |
+ ppc64_elf_unhandled_reloc, /* special_function */
|
|
|
881b8e |
+ "R_PPC64_TPREL16_HIGHA", /* name */
|
|
|
881b8e |
+ FALSE, /* partial_inplace */
|
|
|
881b8e |
+ 0, /* src_mask */
|
|
|
881b8e |
+ 0xffff, /* dst_mask */
|
|
|
881b8e |
+ FALSE), /* pcrel_offset */
|
|
|
881b8e |
+
|
|
|
881b8e |
/* GNU extension to record C++ vtable hierarchy. */
|
|
|
881b8e |
HOWTO (R_PPC64_GNU_VTINHERIT, /* type */
|
|
|
881b8e |
0, /* rightshift */
|
|
|
881b8e |
@@ -2066,8 +2174,12 @@ ppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
|
|
881b8e |
break;
|
|
|
881b8e |
case BFD_RELOC_HI16: r = R_PPC64_ADDR16_HI;
|
|
|
881b8e |
break;
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_ADDR16_HIGH: r = R_PPC64_ADDR16_HIGH;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
case BFD_RELOC_HI16_S: r = R_PPC64_ADDR16_HA;
|
|
|
881b8e |
break;
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_ADDR16_HIGHA: r = R_PPC64_ADDR16_HIGHA;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
case BFD_RELOC_PPC_BA16: r = R_PPC64_ADDR14;
|
|
|
881b8e |
break;
|
|
|
881b8e |
case BFD_RELOC_PPC_BA16_BRTAKEN: r = R_PPC64_ADDR14_BRTAKEN;
|
|
|
881b8e |
@@ -2186,8 +2298,12 @@ ppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
|
|
881b8e |
break;
|
|
|
881b8e |
case BFD_RELOC_PPC_TPREL16_HI: r = R_PPC64_TPREL16_HI;
|
|
|
881b8e |
break;
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_TPREL16_HIGH: r = R_PPC64_TPREL16_HIGH;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
case BFD_RELOC_PPC_TPREL16_HA: r = R_PPC64_TPREL16_HA;
|
|
|
881b8e |
break;
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_TPREL16_HIGHA: r = R_PPC64_TPREL16_HIGHA;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
case BFD_RELOC_PPC_TPREL: r = R_PPC64_TPREL64;
|
|
|
881b8e |
break;
|
|
|
881b8e |
case BFD_RELOC_PPC_DTPREL16: r = R_PPC64_DTPREL16;
|
|
|
881b8e |
@@ -2196,8 +2312,12 @@ ppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
|
|
881b8e |
break;
|
|
|
881b8e |
case BFD_RELOC_PPC_DTPREL16_HI: r = R_PPC64_DTPREL16_HI;
|
|
|
881b8e |
break;
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_DTPREL16_HIGH: r = R_PPC64_DTPREL16_HIGH;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
case BFD_RELOC_PPC_DTPREL16_HA: r = R_PPC64_DTPREL16_HA;
|
|
|
881b8e |
break;
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_DTPREL16_HIGHA: r = R_PPC64_DTPREL16_HIGHA;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
case BFD_RELOC_PPC_DTPREL: r = R_PPC64_DTPREL64;
|
|
|
881b8e |
break;
|
|
|
881b8e |
case BFD_RELOC_PPC_GOT_TLSGD16: r = R_PPC64_GOT_TLSGD16;
|
|
|
881b8e |
@@ -2836,6 +2956,19 @@ get_opd_info (asection * sec)
|
|
|
881b8e |
return &ppc64_elf_section_data (sec)->u.opd;
|
|
|
881b8e |
return NULL;
|
|
|
881b8e |
}
|
|
|
881b8e |
+
|
|
|
881b8e |
+static inline int
|
|
|
881b8e |
+abiversion (bfd *abfd)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ return elf_elfheader (abfd)->e_flags & EF_PPC64_ABI;
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
+static inline void
|
|
|
881b8e |
+set_abiversion (bfd *abfd, int ver)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ elf_elfheader (abfd)->e_flags &= ~EF_PPC64_ABI;
|
|
|
881b8e |
+ elf_elfheader (abfd)->e_flags |= ver & EF_PPC64_ABI;
|
|
|
881b8e |
+}
|
|
|
881b8e |
|
|
|
881b8e |
/* Parameters for the qsort hook. */
|
|
|
881b8e |
static bfd_boolean synthetic_relocatable;
|
|
|
881b8e |
@@ -2982,15 +3115,19 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
|
|
|
881b8e |
long count;
|
|
|
881b8e |
char *names;
|
|
|
881b8e |
long symcount, codesecsym, codesecsymend, secsymend, opdsymend;
|
|
|
881b8e |
- asection *opd;
|
|
|
881b8e |
+ asection *opd = NULL;
|
|
|
881b8e |
bfd_boolean relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
|
|
|
881b8e |
asymbol **syms;
|
|
|
881b8e |
+ int abi = abiversion (abfd);
|
|
|
881b8e |
|
|
|
881b8e |
*ret = NULL;
|
|
|
881b8e |
|
|
|
881b8e |
- opd = bfd_get_section_by_name (abfd, ".opd");
|
|
|
881b8e |
- if (opd == NULL)
|
|
|
881b8e |
- return 0;
|
|
|
881b8e |
+ if (abi < 2)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ opd = bfd_get_section_by_name (abfd, ".opd");
|
|
|
881b8e |
+ if (opd == NULL && abi == 1)
|
|
|
881b8e |
+ return 0;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
|
|
|
881b8e |
symcount = static_count;
|
|
|
881b8e |
if (!relocatable)
|
|
|
881b8e |
@@ -3159,20 +3296,18 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
|
|
|
881b8e |
else
|
|
|
881b8e |
{
|
|
|
881b8e |
bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
|
|
|
881b8e |
- bfd_byte *contents;
|
|
|
881b8e |
+ bfd_byte *contents = NULL;
|
|
|
881b8e |
size_t size;
|
|
|
881b8e |
long plt_count = 0;
|
|
|
881b8e |
bfd_vma glink_vma = 0, resolv_vma = 0;
|
|
|
881b8e |
asection *dynamic, *glink = NULL, *relplt = NULL;
|
|
|
881b8e |
arelent *p;
|
|
|
881b8e |
|
|
|
881b8e |
- if (!bfd_malloc_and_get_section (abfd, opd, &contents))
|
|
|
881b8e |
+ if (opd != NULL && !bfd_malloc_and_get_section (abfd, opd, &contents))
|
|
|
881b8e |
{
|
|
|
881b8e |
+ free_contents_and_exit:
|
|
|
881b8e |
if (contents)
|
|
|
881b8e |
- {
|
|
|
881b8e |
- free_contents_and_exit:
|
|
|
881b8e |
- free (contents);
|
|
|
881b8e |
- }
|
|
|
881b8e |
+ free (contents);
|
|
|
881b8e |
count = -1;
|
|
|
881b8e |
goto done;
|
|
|
881b8e |
}
|
|
|
881b8e |
@@ -3221,9 +3356,9 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
|
|
|
881b8e |
|
|
|
881b8e |
if (dyn.d_tag == DT_PPC64_GLINK)
|
|
|
881b8e |
{
|
|
|
881b8e |
- /* The first glink stub starts at offset 32; see comment in
|
|
|
881b8e |
- ppc64_elf_finish_dynamic_sections. */
|
|
|
881b8e |
- glink_vma = dyn.d_un.d_val + 32;
|
|
|
881b8e |
+ /* The first glink stub starts at offset 32; see
|
|
|
881b8e |
+ comment in ppc64_elf_finish_dynamic_sections. */
|
|
|
881b8e |
+ glink_vma = dyn.d_un.d_val + GLINK_CALL_STUB_SIZE - 8 * 4;
|
|
|
881b8e |
/* The .glink section usually does not survive the final
|
|
|
881b8e |
link; search for the section (usually .text) where the
|
|
|
881b8e |
glink stubs now reside. */
|
|
|
881b8e |
@@ -3241,13 +3376,21 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
|
|
|
881b8e |
/* Determine __glink trampoline by reading the relative branch
|
|
|
881b8e |
from the first glink stub. */
|
|
|
881b8e |
bfd_byte buf[4];
|
|
|
881b8e |
- if (bfd_get_section_contents (abfd, glink, buf,
|
|
|
881b8e |
- glink_vma + 4 - glink->vma, 4))
|
|
|
881b8e |
+ unsigned int off = 0;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ while (bfd_get_section_contents (abfd, glink, buf,
|
|
|
881b8e |
+ glink_vma + off - glink->vma, 4))
|
|
|
881b8e |
{
|
|
|
881b8e |
unsigned int insn = bfd_get_32 (abfd, buf);
|
|
|
881b8e |
insn ^= B_DOT;
|
|
|
881b8e |
if ((insn & ~0x3fffffc) == 0)
|
|
|
881b8e |
- resolv_vma = glink_vma + 4 + (insn ^ 0x2000000) - 0x2000000;
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ resolv_vma = glink_vma + off + (insn ^ 0x2000000) - 0x2000000;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ off += 4;
|
|
|
881b8e |
+ if (off > 4)
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
if (resolv_vma)
|
|
|
881b8e |
@@ -3400,8 +3543,13 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
|
|
|
881b8e |
memcpy (names, "@plt", sizeof ("@plt"));
|
|
|
881b8e |
names += sizeof ("@plt");
|
|
|
881b8e |
s++;
|
|
|
881b8e |
- glink_vma += 8;
|
|
|
881b8e |
- if (i >= 0x8000)
|
|
|
881b8e |
+ if (abi < 2)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ glink_vma += 8;
|
|
|
881b8e |
+ if (i >= 0x8000)
|
|
|
881b8e |
+ glink_vma += 4;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ else
|
|
|
881b8e |
glink_vma += 4;
|
|
|
881b8e |
}
|
|
|
881b8e |
count += plt_count;
|
|
|
881b8e |
@@ -3452,13 +3600,13 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
|
|
|
881b8e |
.
|
|
|
881b8e |
.
|
|
|
881b8e |
. .foo_stub:
|
|
|
881b8e |
- . addis 12,2,Lfoo@toc@ha # in practice, the call stub
|
|
|
881b8e |
- . addi 12,12,Lfoo@toc@l # is slightly optimized, but
|
|
|
881b8e |
- . std 2,40(1) # this is the general idea
|
|
|
881b8e |
- . ld 11,0(12)
|
|
|
881b8e |
- . ld 2,8(12)
|
|
|
881b8e |
- . mtctr 11
|
|
|
881b8e |
- . ld 11,16(12)
|
|
|
881b8e |
+ . std 2,40(1) # in practice, the call stub
|
|
|
881b8e |
+ . addis 11,2,Lfoo@toc@ha # is slightly optimized, but
|
|
|
881b8e |
+ . addi 11,11,Lfoo@toc@l # this is the general idea
|
|
|
881b8e |
+ . ld 12,0(11)
|
|
|
881b8e |
+ . ld 2,8(11)
|
|
|
881b8e |
+ . mtctr 12
|
|
|
881b8e |
+ . ld 11,16(11)
|
|
|
881b8e |
. bctr
|
|
|
881b8e |
.
|
|
|
881b8e |
. .section .plt
|
|
|
881b8e |
@@ -3509,6 +3657,8 @@ must_be_dyn_reloc (struct bfd_link_info *info,
|
|
|
881b8e |
case R_PPC64_TPREL16_HA:
|
|
|
881b8e |
case R_PPC64_TPREL16_DS:
|
|
|
881b8e |
case R_PPC64_TPREL16_LO_DS:
|
|
|
881b8e |
+ case R_PPC64_TPREL16_HIGH:
|
|
|
881b8e |
+ case R_PPC64_TPREL16_HIGHA:
|
|
|
881b8e |
case R_PPC64_TPREL16_HIGHER:
|
|
|
881b8e |
case R_PPC64_TPREL16_HIGHERA:
|
|
|
881b8e |
case R_PPC64_TPREL16_HIGHEST:
|
|
|
881b8e |
@@ -3548,21 +3698,21 @@ must_be_dyn_reloc (struct bfd_link_info *info,
|
|
|
881b8e |
ppc_stub_plt_branch:
|
|
|
881b8e |
Similar to the above, but a 24 bit branch in the stub section won't
|
|
|
881b8e |
reach its destination.
|
|
|
881b8e |
- . addis %r12,%r2,xxx@toc@ha
|
|
|
881b8e |
- . ld %r11,xxx@toc@l(%r12)
|
|
|
881b8e |
- . mtctr %r11
|
|
|
881b8e |
+ . addis %r11,%r2,xxx@toc@ha
|
|
|
881b8e |
+ . ld %r12,xxx@toc@l(%r11)
|
|
|
881b8e |
+ . mtctr %r12
|
|
|
881b8e |
. bctr
|
|
|
881b8e |
|
|
|
881b8e |
ppc_stub_plt_call:
|
|
|
881b8e |
Used to call a function in a shared library. If it so happens that
|
|
|
881b8e |
the plt entry referenced crosses a 64k boundary, then an extra
|
|
|
881b8e |
- "addi %r12,%r12,xxx@toc@l" will be inserted before the "mtctr".
|
|
|
881b8e |
- . addis %r12,%r2,xxx@toc@ha
|
|
|
881b8e |
+ "addi %r11,%r11,xxx@toc@l" will be inserted before the "mtctr".
|
|
|
881b8e |
. std %r2,40(%r1)
|
|
|
881b8e |
- . ld %r11,xxx+0@toc@l(%r12)
|
|
|
881b8e |
- . mtctr %r11
|
|
|
881b8e |
- . ld %r2,xxx+8@toc@l(%r12)
|
|
|
881b8e |
- . ld %r11,xxx+16@toc@l(%r12)
|
|
|
881b8e |
+ . addis %r11,%r2,xxx@toc@ha
|
|
|
881b8e |
+ . ld %r12,xxx+0@toc@l(%r11)
|
|
|
881b8e |
+ . mtctr %r12
|
|
|
881b8e |
+ . ld %r2,xxx+8@toc@l(%r11)
|
|
|
881b8e |
+ . ld %r11,xxx+16@toc@l(%r11)
|
|
|
881b8e |
. bctr
|
|
|
881b8e |
|
|
|
881b8e |
ppc_stub_long_branch and ppc_stub_plt_branch may also have additional
|
|
|
881b8e |
@@ -3575,11 +3725,11 @@ must_be_dyn_reloc (struct bfd_link_info *info,
|
|
|
881b8e |
|
|
|
881b8e |
A ppc_stub_plt_branch with an r2 offset looks like:
|
|
|
881b8e |
. std %r2,40(%r1)
|
|
|
881b8e |
- . addis %r12,%r2,xxx@toc@ha
|
|
|
881b8e |
- . ld %r11,xxx@toc@l(%r12)
|
|
|
881b8e |
+ . addis %r11,%r2,xxx@toc@ha
|
|
|
881b8e |
+ . ld %r12,xxx@toc@l(%r11)
|
|
|
881b8e |
. addis %r2,%r2,off@ha
|
|
|
881b8e |
. addi %r2,%r2,off@l
|
|
|
881b8e |
- . mtctr %r11
|
|
|
881b8e |
+ . mtctr %r12
|
|
|
881b8e |
. bctr
|
|
|
881b8e |
|
|
|
881b8e |
In cases where the "addis" instruction would add zero, the "addis" is
|
|
|
881b8e |
@@ -3624,6 +3774,9 @@ struct ppc_stub_hash_entry {
|
|
|
881b8e |
/* Where this stub is being called from, or, in the case of combined
|
|
|
881b8e |
stub sections, the first input section in the group. */
|
|
|
881b8e |
asection *id_sec;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ /* Symbol st_other. */
|
|
|
881b8e |
+ unsigned char other;
|
|
|
881b8e |
};
|
|
|
881b8e |
|
|
|
881b8e |
struct ppc_branch_hash_entry {
|
|
|
881b8e |
@@ -3772,6 +3925,9 @@ struct ppc_link_hash_table
|
|
|
881b8e |
/* Alignment of PLT call stubs. */
|
|
|
881b8e |
unsigned int plt_stub_align:4;
|
|
|
881b8e |
|
|
|
881b8e |
+ /* Set if we're linking code with function descriptors. */
|
|
|
881b8e |
+ unsigned int opd_abi:1;
|
|
|
881b8e |
+
|
|
|
881b8e |
/* Set if PLT call stubs should load r11. */
|
|
|
881b8e |
unsigned int plt_static_chain:1;
|
|
|
881b8e |
|
|
|
881b8e |
@@ -3867,7 +4023,9 @@ stub_hash_newfunc (struct bfd_hash_entry *entry,
|
|
|
881b8e |
eh->target_value = 0;
|
|
|
881b8e |
eh->target_section = NULL;
|
|
|
881b8e |
eh->h = NULL;
|
|
|
881b8e |
+ eh->plt_ent = NULL;
|
|
|
881b8e |
eh->id_sec = NULL;
|
|
|
881b8e |
+ eh->other = 0;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
return entry;
|
|
|
881b8e |
@@ -4452,6 +4610,7 @@ ppc64_elf_copy_indirect_symbol (struct bfd_link_info *info,
|
|
|
881b8e |
edir->elf.ref_regular |= eind->elf.ref_regular;
|
|
|
881b8e |
edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak;
|
|
|
881b8e |
edir->elf.needs_plt |= eind->elf.needs_plt;
|
|
|
881b8e |
+ edir->elf.pointer_equality_needed |= eind->elf.pointer_equality_needed;
|
|
|
881b8e |
|
|
|
881b8e |
/* Copy over any dynamic relocs we may have on the indirect sym. */
|
|
|
881b8e |
if (eind->dyn_relocs != NULL)
|
|
|
881b8e |
@@ -4610,7 +4769,7 @@ static bfd_boolean
|
|
|
881b8e |
ppc64_elf_add_symbol_hook (bfd *ibfd,
|
|
|
881b8e |
struct bfd_link_info *info,
|
|
|
881b8e |
Elf_Internal_Sym *isym,
|
|
|
881b8e |
- const char **name ATTRIBUTE_UNUSED,
|
|
|
881b8e |
+ const char **name,
|
|
|
881b8e |
flagword *flags ATTRIBUTE_UNUSED,
|
|
|
881b8e |
asection **sec,
|
|
|
881b8e |
bfd_vma *value ATTRIBUTE_UNUSED)
|
|
|
881b8e |
@@ -4630,9 +4789,35 @@ ppc64_elf_add_symbol_hook (bfd *ibfd,
|
|
|
881b8e |
&& strcmp ((*sec)->name, ".opd") == 0)
|
|
|
881b8e |
isym->st_info = ELF_ST_INFO (ELF_ST_BIND (isym->st_info), STT_FUNC);
|
|
|
881b8e |
|
|
|
881b8e |
+ if ((STO_PPC64_LOCAL_MASK & isym->st_other) != 0)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ if (abiversion (ibfd) == 0)
|
|
|
881b8e |
+ set_abiversion (ibfd, 2);
|
|
|
881b8e |
+ else if (abiversion (ibfd) == 1)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ info->callbacks->einfo (_("%P: symbol '%s' has invalid st_other"
|
|
|
881b8e |
+ " for ABI version 1\n"), name);
|
|
|
881b8e |
+ bfd_set_error (bfd_error_bad_value);
|
|
|
881b8e |
+ return FALSE;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+
|
|
|
881b8e |
return TRUE;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
+/* Merge non-visibility st_other attributes: local entry point. */
|
|
|
881b8e |
+
|
|
|
881b8e |
+static void
|
|
|
881b8e |
+ppc64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
|
|
|
881b8e |
+ const Elf_Internal_Sym *isym,
|
|
|
881b8e |
+ bfd_boolean definition,
|
|
|
881b8e |
+ bfd_boolean dynamic)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ if (definition && !dynamic)
|
|
|
881b8e |
+ h->other = ((isym->st_other & ~ELF_ST_VISIBILITY (-1))
|
|
|
881b8e |
+ | ELF_ST_VISIBILITY (h->other));
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
/* This function makes an old ABI object reference to ".bar" cause the
|
|
|
881b8e |
inclusion of a new ABI object archive that defines "bar".
|
|
|
881b8e |
NAME is a symbol defined in an archive. Return a symbol in the hash
|
|
|
881b8e |
@@ -4959,6 +5144,15 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|
|
881b8e |
information about the associated function section. */
|
|
|
881b8e |
bfd_size_type amt;
|
|
|
881b8e |
|
|
|
881b8e |
+ if (abiversion (abfd) == 0)
|
|
|
881b8e |
+ set_abiversion (abfd, 1);
|
|
|
881b8e |
+ else if (abiversion (abfd) == 2)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ info->callbacks->einfo (_("%P: .opd not allowed in ABI version %d\n"),
|
|
|
881b8e |
+ abiversion (abfd));
|
|
|
881b8e |
+ bfd_set_error (bfd_error_bad_value);
|
|
|
881b8e |
+ return FALSE;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
amt = sec->size * sizeof (*opd_sym_map) / 8;
|
|
|
881b8e |
opd_sym_map = bfd_zalloc (abfd, amt);
|
|
|
881b8e |
if (opd_sym_map == NULL)
|
|
|
881b8e |
@@ -5134,6 +5328,14 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|
|
881b8e |
if (!update_local_sym_info (abfd, symtab_hdr, r_symndx,
|
|
|
881b8e |
rel->r_addend, tls_type))
|
|
|
881b8e |
return FALSE;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ /* We may also need a plt entry if the symbol turns out to be
|
|
|
881b8e |
+ an ifunc. */
|
|
|
881b8e |
+ if (h != NULL && !info->shared && abiversion (abfd) == 2)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ if (!update_plt_info (abfd, &h->plt.plist, rel->r_addend))
|
|
|
881b8e |
+ return FALSE;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
case R_PPC64_PLT16_HA:
|
|
|
881b8e |
@@ -5179,6 +5381,8 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|
|
881b8e |
case R_PPC64_DTPREL16_HA:
|
|
|
881b8e |
case R_PPC64_DTPREL16_DS:
|
|
|
881b8e |
case R_PPC64_DTPREL16_LO_DS:
|
|
|
881b8e |
+ case R_PPC64_DTPREL16_HIGH:
|
|
|
881b8e |
+ case R_PPC64_DTPREL16_HIGHA:
|
|
|
881b8e |
case R_PPC64_DTPREL16_HIGHER:
|
|
|
881b8e |
case R_PPC64_DTPREL16_HIGHERA:
|
|
|
881b8e |
case R_PPC64_DTPREL16_HIGHEST:
|
|
|
881b8e |
@@ -5339,6 +5543,8 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|
|
881b8e |
case R_PPC64_TPREL16_HA:
|
|
|
881b8e |
case R_PPC64_TPREL16_DS:
|
|
|
881b8e |
case R_PPC64_TPREL16_LO_DS:
|
|
|
881b8e |
+ case R_PPC64_TPREL16_HIGH:
|
|
|
881b8e |
+ case R_PPC64_TPREL16_HIGHA:
|
|
|
881b8e |
case R_PPC64_TPREL16_HIGHER:
|
|
|
881b8e |
case R_PPC64_TPREL16_HIGHERA:
|
|
|
881b8e |
case R_PPC64_TPREL16_HIGHEST:
|
|
|
881b8e |
@@ -5382,22 +5588,35 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|
|
881b8e |
}
|
|
|
881b8e |
/* Fall through. */
|
|
|
881b8e |
|
|
|
881b8e |
- case R_PPC64_REL30:
|
|
|
881b8e |
- case R_PPC64_REL32:
|
|
|
881b8e |
- case R_PPC64_REL64:
|
|
|
881b8e |
- case R_PPC64_ADDR14:
|
|
|
881b8e |
- case R_PPC64_ADDR14_BRNTAKEN:
|
|
|
881b8e |
- case R_PPC64_ADDR14_BRTAKEN:
|
|
|
881b8e |
case R_PPC64_ADDR16:
|
|
|
881b8e |
case R_PPC64_ADDR16_DS:
|
|
|
881b8e |
case R_PPC64_ADDR16_HA:
|
|
|
881b8e |
case R_PPC64_ADDR16_HI:
|
|
|
881b8e |
+ case R_PPC64_ADDR16_HIGH:
|
|
|
881b8e |
+ case R_PPC64_ADDR16_HIGHA:
|
|
|
881b8e |
case R_PPC64_ADDR16_HIGHER:
|
|
|
881b8e |
case R_PPC64_ADDR16_HIGHERA:
|
|
|
881b8e |
case R_PPC64_ADDR16_HIGHEST:
|
|
|
881b8e |
case R_PPC64_ADDR16_HIGHESTA:
|
|
|
881b8e |
case R_PPC64_ADDR16_LO:
|
|
|
881b8e |
case R_PPC64_ADDR16_LO_DS:
|
|
|
881b8e |
+ if (h != NULL && !info->shared && abiversion (abfd) == 2
|
|
|
881b8e |
+ && rel->r_addend == 0)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ /* We may need a .plt entry if this reloc refers to a
|
|
|
881b8e |
+ function in a shared lib. */
|
|
|
881b8e |
+ if (!update_plt_info (abfd, &h->plt.plist, rel->r_addend))
|
|
|
881b8e |
+ return FALSE;
|
|
|
881b8e |
+ h->pointer_equality_needed = 1;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ /* Fall through. */
|
|
|
881b8e |
+
|
|
|
881b8e |
+ case R_PPC64_REL30:
|
|
|
881b8e |
+ case R_PPC64_REL32:
|
|
|
881b8e |
+ case R_PPC64_REL64:
|
|
|
881b8e |
+ case R_PPC64_ADDR14:
|
|
|
881b8e |
+ case R_PPC64_ADDR14_BRNTAKEN:
|
|
|
881b8e |
+ case R_PPC64_ADDR14_BRTAKEN:
|
|
|
881b8e |
case R_PPC64_ADDR24:
|
|
|
881b8e |
case R_PPC64_ADDR32:
|
|
|
881b8e |
case R_PPC64_UADDR16:
|
|
|
881b8e |
@@ -5518,6 +5737,78 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|
|
881b8e |
return TRUE;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
+/* Merge backend specific data from an object file to the output
|
|
|
881b8e |
+ object file when linking. */
|
|
|
881b8e |
+
|
|
|
881b8e |
+static bfd_boolean
|
|
|
881b8e |
+ppc64_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ unsigned long iflags, oflags;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if ((ibfd->flags & BFD_LINKER_CREATED) != 0)
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (!is_ppc64_elf (ibfd) || !is_ppc64_elf (obfd))
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (!_bfd_generic_verify_endian_match (ibfd, obfd))
|
|
|
881b8e |
+ return FALSE;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ iflags = elf_elfheader (ibfd)->e_flags;
|
|
|
881b8e |
+ oflags = elf_elfheader (obfd)->e_flags;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (!elf_flags_init (obfd) || oflags == 0)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ elf_flags_init (obfd) = TRUE;
|
|
|
881b8e |
+ elf_elfheader (obfd)->e_flags = iflags;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ else if (iflags == oflags || iflags == 0)
|
|
|
881b8e |
+ ;
|
|
|
881b8e |
+ else if (iflags & ~EF_PPC64_ABI)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ (*_bfd_error_handler)
|
|
|
881b8e |
+ (_("%B uses unknown e_flags 0x%lx"), ibfd, iflags);
|
|
|
881b8e |
+ bfd_set_error (bfd_error_bad_value);
|
|
|
881b8e |
+ return FALSE;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ else
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ (*_bfd_error_handler)
|
|
|
881b8e |
+ (_("%B: ABI version %ld is not compatible with ABI version %ld output"),
|
|
|
881b8e |
+ ibfd, iflags, oflags);
|
|
|
881b8e |
+ bfd_set_error (bfd_error_bad_value);
|
|
|
881b8e |
+ return FALSE;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+
|
|
|
881b8e |
+ /* Merge Tag_compatibility attributes and any common GNU ones. */
|
|
|
881b8e |
+ _bfd_elf_merge_object_attributes (ibfd, obfd);
|
|
|
881b8e |
+
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
+static bfd_boolean
|
|
|
881b8e |
+ppc64_elf_print_private_bfd_data (bfd *abfd, void *ptr)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ /* Print normal ELF private data. */
|
|
|
881b8e |
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (elf_elfheader (abfd)->e_flags != 0)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ FILE *file = ptr;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ /* xgettext:c-format */
|
|
|
881b8e |
+ fprintf (file, _("private flags = 0x%lx:"),
|
|
|
881b8e |
+ elf_elfheader (abfd)->e_flags);
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if ((elf_elfheader (abfd)->e_flags & EF_PPC64_ABI) != 0)
|
|
|
881b8e |
+ fprintf (file, _(" [abiv%ld]"),
|
|
|
881b8e |
+ elf_elfheader (abfd)->e_flags & EF_PPC64_ABI);
|
|
|
881b8e |
+ fputc ('\n', file);
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
/* OFFSET in OPD_SEC specifies a function descriptor. Return the address
|
|
|
881b8e |
of the code entry point, and its section. */
|
|
|
881b8e |
|
|
|
881b8e |
@@ -6177,7 +6468,7 @@ static bfd_byte *
|
|
|
881b8e |
savegpr0_tail (bfd *abfd, bfd_byte *p, int r)
|
|
|
881b8e |
{
|
|
|
881b8e |
p = savegpr0 (abfd, p, r);
|
|
|
881b8e |
- bfd_put_32 (abfd, STD_R0_0R1 + 16, p);
|
|
|
881b8e |
+ bfd_put_32 (abfd, STD_R0_0R1 + STK_LR, p);
|
|
|
881b8e |
p = p + 4;
|
|
|
881b8e |
bfd_put_32 (abfd, BLR, p);
|
|
|
881b8e |
return p + 4;
|
|
|
881b8e |
@@ -6193,7 +6484,7 @@ restgpr0 (bfd *abfd, bfd_byte *p, int r)
|
|
|
881b8e |
static bfd_byte *
|
|
|
881b8e |
restgpr0_tail (bfd *abfd, bfd_byte *p, int r)
|
|
|
881b8e |
{
|
|
|
881b8e |
- bfd_put_32 (abfd, LD_R0_0R1 + 16, p);
|
|
|
881b8e |
+ bfd_put_32 (abfd, LD_R0_0R1 + STK_LR, p);
|
|
|
881b8e |
p = p + 4;
|
|
|
881b8e |
p = restgpr0 (abfd, p, r);
|
|
|
881b8e |
bfd_put_32 (abfd, MTLR_R0, p);
|
|
|
881b8e |
@@ -6248,7 +6539,7 @@ static bfd_byte *
|
|
|
881b8e |
savefpr0_tail (bfd *abfd, bfd_byte *p, int r)
|
|
|
881b8e |
{
|
|
|
881b8e |
p = savefpr (abfd, p, r);
|
|
|
881b8e |
- bfd_put_32 (abfd, STD_R0_0R1 + 16, p);
|
|
|
881b8e |
+ bfd_put_32 (abfd, STD_R0_0R1 + STK_LR, p);
|
|
|
881b8e |
p = p + 4;
|
|
|
881b8e |
bfd_put_32 (abfd, BLR, p);
|
|
|
881b8e |
return p + 4;
|
|
|
881b8e |
@@ -6264,7 +6555,7 @@ restfpr (bfd *abfd, bfd_byte *p, int r)
|
|
|
881b8e |
static bfd_byte *
|
|
|
881b8e |
restfpr0_tail (bfd *abfd, bfd_byte *p, int r)
|
|
|
881b8e |
{
|
|
|
881b8e |
- bfd_put_32 (abfd, LD_R0_0R1 + 16, p);
|
|
|
881b8e |
+ bfd_put_32 (abfd, LD_R0_0R1 + STK_LR, p);
|
|
|
881b8e |
p = p + 4;
|
|
|
881b8e |
p = restfpr (abfd, p, r);
|
|
|
881b8e |
bfd_put_32 (abfd, MTLR_R0, p);
|
|
|
881b8e |
@@ -6510,6 +6801,25 @@ ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED,
|
|
|
881b8e |
return TRUE;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
+/* Return true if we have dynamic relocs that apply to read-only sections. */
|
|
|
881b8e |
+
|
|
|
881b8e |
+static bfd_boolean
|
|
|
881b8e |
+readonly_dynrelocs (struct elf_link_hash_entry *h)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ struct ppc_link_hash_entry *eh;
|
|
|
881b8e |
+ struct elf_dyn_relocs *p;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ eh = (struct ppc_link_hash_entry *) h;
|
|
|
881b8e |
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ asection *s = p->sec->output_section;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ return FALSE;
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
/* Adjust a symbol defined by a dynamic object and referenced by a
|
|
|
881b8e |
regular object. The current definition is in some section of the
|
|
|
881b8e |
dynamic object, but we're not including those sections. We have to
|
|
|
881b8e |
@@ -6547,6 +6857,26 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
|
|
|
881b8e |
h->plt.plist = NULL;
|
|
|
881b8e |
h->needs_plt = 0;
|
|
|
881b8e |
}
|
|
|
881b8e |
+ else if (abiversion (info->output_bfd) == 2)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ /* After adjust_dynamic_symbol, non_got_ref set in the
|
|
|
881b8e |
+ non-shared case means that we have allocated space in
|
|
|
881b8e |
+ .dynbss for the symbol and thus dyn_relocs for this
|
|
|
881b8e |
+ symbol should be discarded.
|
|
|
881b8e |
+ If we get here we know we are making a PLT entry for this
|
|
|
881b8e |
+ symbol, and in an executable we'd normally resolve
|
|
|
881b8e |
+ relocations against this symbol to the PLT entry. Allow
|
|
|
881b8e |
+ dynamic relocs if the reference is weak, and the dynamic
|
|
|
881b8e |
+ relocs will not cause text relocation. */
|
|
|
881b8e |
+ if (!h->ref_regular_nonweak
|
|
|
881b8e |
+ && h->non_got_ref
|
|
|
881b8e |
+ && h->type != STT_GNU_IFUNC
|
|
|
881b8e |
+ && !readonly_dynrelocs (h))
|
|
|
881b8e |
+ h->non_got_ref = 0;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ /* If making a plt entry, then we don't need copy relocs. */
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
}
|
|
|
881b8e |
else
|
|
|
881b8e |
h->plt.plist = NULL;
|
|
|
881b8e |
@@ -6581,26 +6911,12 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
|
|
|
881b8e |
if (!h->def_dynamic || !h->ref_regular || h->def_regular)
|
|
|
881b8e |
return TRUE;
|
|
|
881b8e |
|
|
|
881b8e |
- if (ELIMINATE_COPY_RELOCS)
|
|
|
881b8e |
+ /* If we didn't find any dynamic relocs in read-only sections, then
|
|
|
881b8e |
+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
|
|
|
881b8e |
+ if (ELIMINATE_COPY_RELOCS && !readonly_dynrelocs (h))
|
|
|
881b8e |
{
|
|
|
881b8e |
- struct ppc_link_hash_entry * eh;
|
|
|
881b8e |
- struct elf_dyn_relocs *p;
|
|
|
881b8e |
-
|
|
|
881b8e |
- eh = (struct ppc_link_hash_entry *) h;
|
|
|
881b8e |
- for (p = eh->dyn_relocs; p != NULL; p = p->next)
|
|
|
881b8e |
- {
|
|
|
881b8e |
- s = p->sec->output_section;
|
|
|
881b8e |
- if (s != NULL && (s->flags & SEC_READONLY) != 0)
|
|
|
881b8e |
- break;
|
|
|
881b8e |
- }
|
|
|
881b8e |
-
|
|
|
881b8e |
- /* If we didn't find any dynamic relocs in read-only sections, then
|
|
|
881b8e |
- we'll be keeping the dynamic relocs and avoiding the copy reloc. */
|
|
|
881b8e |
- if (p == NULL)
|
|
|
881b8e |
- {
|
|
|
881b8e |
- h->non_got_ref = 0;
|
|
|
881b8e |
- return TRUE;
|
|
|
881b8e |
- }
|
|
|
881b8e |
+ h->non_got_ref = 0;
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
if (h->plt.plist != NULL)
|
|
|
881b8e |
@@ -6980,6 +7296,8 @@ dec_dynrel_count (bfd_vma r_info,
|
|
|
881b8e |
case R_PPC64_TPREL16_HA:
|
|
|
881b8e |
case R_PPC64_TPREL16_DS:
|
|
|
881b8e |
case R_PPC64_TPREL16_LO_DS:
|
|
|
881b8e |
+ case R_PPC64_TPREL16_HIGH:
|
|
|
881b8e |
+ case R_PPC64_TPREL16_HIGHA:
|
|
|
881b8e |
case R_PPC64_TPREL16_HIGHER:
|
|
|
881b8e |
case R_PPC64_TPREL16_HIGHERA:
|
|
|
881b8e |
case R_PPC64_TPREL16_HIGHEST:
|
|
|
881b8e |
@@ -7001,6 +7319,8 @@ dec_dynrel_count (bfd_vma r_info,
|
|
|
881b8e |
case R_PPC64_ADDR16_DS:
|
|
|
881b8e |
case R_PPC64_ADDR16_HA:
|
|
|
881b8e |
case R_PPC64_ADDR16_HI:
|
|
|
881b8e |
+ case R_PPC64_ADDR16_HIGH:
|
|
|
881b8e |
+ case R_PPC64_ADDR16_HIGHA:
|
|
|
881b8e |
case R_PPC64_ADDR16_HIGHER:
|
|
|
881b8e |
case R_PPC64_ADDR16_HIGHERA:
|
|
|
881b8e |
case R_PPC64_ADDR16_HIGHEST:
|
|
|
881b8e |
@@ -7504,6 +7824,9 @@ ppc64_elf_tls_setup (struct bfd_link_info *info,
|
|
|
881b8e |
if (htab == NULL)
|
|
|
881b8e |
return NULL;
|
|
|
881b8e |
|
|
|
881b8e |
+ if (abiversion (info->output_bfd) == 1)
|
|
|
881b8e |
+ htab->opd_abi = 1;
|
|
|
881b8e |
+
|
|
|
881b8e |
if (*no_multi_toc)
|
|
|
881b8e |
htab->do_multi_toc = 0;
|
|
|
881b8e |
else if (!htab->do_multi_toc)
|
|
|
881b8e |
@@ -8287,7 +8610,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
|
|
|
881b8e |
|| discarded_section (sym_sec))
|
|
|
881b8e |
continue;
|
|
|
881b8e |
|
|
|
881b8e |
- if (!SYMBOL_CALLS_LOCAL (info, h))
|
|
|
881b8e |
+ if (!SYMBOL_REFERENCES_LOCAL (info, h))
|
|
|
881b8e |
continue;
|
|
|
881b8e |
|
|
|
881b8e |
if (h != NULL)
|
|
|
881b8e |
@@ -8886,7 +9209,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|
|
881b8e |
{
|
|
|
881b8e |
s = htab->iplt;
|
|
|
881b8e |
pent->plt.offset = s->size;
|
|
|
881b8e |
- s->size += PLT_ENTRY_SIZE;
|
|
|
881b8e |
+ s->size += PLT_ENTRY_SIZE (htab);
|
|
|
881b8e |
s = htab->reliplt;
|
|
|
881b8e |
}
|
|
|
881b8e |
else
|
|
|
881b8e |
@@ -8895,21 +9218,26 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|
|
881b8e |
first entry. */
|
|
|
881b8e |
s = htab->plt;
|
|
|
881b8e |
if (s->size == 0)
|
|
|
881b8e |
- s->size += PLT_INITIAL_ENTRY_SIZE;
|
|
|
881b8e |
+ s->size += PLT_INITIAL_ENTRY_SIZE (htab);
|
|
|
881b8e |
|
|
|
881b8e |
pent->plt.offset = s->size;
|
|
|
881b8e |
|
|
|
881b8e |
/* Make room for this entry. */
|
|
|
881b8e |
- s->size += PLT_ENTRY_SIZE;
|
|
|
881b8e |
+ s->size += PLT_ENTRY_SIZE (htab);
|
|
|
881b8e |
|
|
|
881b8e |
/* Make room for the .glink code. */
|
|
|
881b8e |
s = htab->glink;
|
|
|
881b8e |
if (s->size == 0)
|
|
|
881b8e |
s->size += GLINK_CALL_STUB_SIZE;
|
|
|
881b8e |
- /* We need bigger stubs past index 32767. */
|
|
|
881b8e |
- if (s->size >= GLINK_CALL_STUB_SIZE + 32768*2*4)
|
|
|
881b8e |
+ if (htab->opd_abi)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ /* We need bigger stubs past index 32767. */
|
|
|
881b8e |
+ if (s->size >= GLINK_CALL_STUB_SIZE + 32768*2*4)
|
|
|
881b8e |
+ s->size += 4;
|
|
|
881b8e |
+ s->size += 2*4;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ else
|
|
|
881b8e |
s->size += 4;
|
|
|
881b8e |
- s->size += 2*4;
|
|
|
881b8e |
|
|
|
881b8e |
/* We also need to make an entry in the .rela.plt section. */
|
|
|
881b8e |
s = htab->relplt;
|
|
|
881b8e |
@@ -9002,7 +9330,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|
|
881b8e |
|
|
|
881b8e |
if (eh->dyn_relocs == NULL
|
|
|
881b8e |
|| (!htab->elf.dynamic_sections_created
|
|
|
881b8e |
- && h->type != STT_GNU_IFUNC))
|
|
|
881b8e |
+ && (h->type != STT_GNU_IFUNC
|
|
|
881b8e |
+ || !htab->opd_abi)))
|
|
|
881b8e |
return TRUE;
|
|
|
881b8e |
|
|
|
881b8e |
/* In the shared -Bsymbolic case, discard space allocated for
|
|
|
881b8e |
@@ -9098,28 +9427,65 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|
|
881b8e |
return TRUE;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
-/* Find any dynamic relocs that apply to read-only sections. */
|
|
|
881b8e |
+/* Called via elf_link_hash_traverse from ppc64_elf_size_dynamic_sections
|
|
|
881b8e |
+ to set up space for global entry stubs. These are put in glink,
|
|
|
881b8e |
+ after the branch table. */
|
|
|
881b8e |
|
|
|
881b8e |
static bfd_boolean
|
|
|
881b8e |
-readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|
|
881b8e |
+size_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
|
|
|
881b8e |
{
|
|
|
881b8e |
- struct ppc_link_hash_entry *eh;
|
|
|
881b8e |
- struct elf_dyn_relocs *p;
|
|
|
881b8e |
+ struct bfd_link_info *info;
|
|
|
881b8e |
+ struct ppc_link_hash_table *htab;
|
|
|
881b8e |
+ struct plt_entry *pent;
|
|
|
881b8e |
+ asection *s;
|
|
|
881b8e |
|
|
|
881b8e |
- eh = (struct ppc_link_hash_entry *) h;
|
|
|
881b8e |
- for (p = eh->dyn_relocs; p != NULL; p = p->next)
|
|
|
881b8e |
- {
|
|
|
881b8e |
- asection *s = p->sec->output_section;
|
|
|
881b8e |
+ if (h->root.type == bfd_link_hash_indirect)
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
|
|
|
881b8e |
- if (s != NULL && (s->flags & SEC_READONLY) != 0)
|
|
|
881b8e |
- {
|
|
|
881b8e |
- struct bfd_link_info *info = inf;
|
|
|
881b8e |
+ if (!h->pointer_equality_needed)
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
|
|
|
881b8e |
- info->flags |= DF_TEXTREL;
|
|
|
881b8e |
+ if (h->def_regular)
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
|
|
|
881b8e |
- /* Not an error, just cut short the traversal. */
|
|
|
881b8e |
- return FALSE;
|
|
|
881b8e |
- }
|
|
|
881b8e |
+ info = inf;
|
|
|
881b8e |
+ htab = ppc_hash_table (info);
|
|
|
881b8e |
+ if (htab == NULL)
|
|
|
881b8e |
+ return FALSE;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ s = htab->glink;
|
|
|
881b8e |
+ for (pent = h->plt.plist; pent != NULL; pent = pent->next)
|
|
|
881b8e |
+ if (pent->plt.offset != (bfd_vma) -1
|
|
|
881b8e |
+ && pent->addend == 0)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ /* For ELFv2, if this symbol is not defined in a regular file
|
|
|
881b8e |
+ and we are not generating a shared library or pie, then we
|
|
|
881b8e |
+ need to define the symbol in the executable on a call stub.
|
|
|
881b8e |
+ This is to avoid text relocations. */
|
|
|
881b8e |
+ s->size = (s->size + 15) & -16;
|
|
|
881b8e |
+ h->root.u.def.section = s;
|
|
|
881b8e |
+ h->root.u.def.value = s->size;
|
|
|
881b8e |
+ s->size += 16;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
+/* Set DF_TEXTREL if we find any dynamic relocs that apply to
|
|
|
881b8e |
+ read-only sections. */
|
|
|
881b8e |
+
|
|
|
881b8e |
+static bfd_boolean
|
|
|
881b8e |
+maybe_set_textrel (struct elf_link_hash_entry *h, void *info)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ if (h->root.type == bfd_link_hash_indirect)
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (readonly_dynrelocs (h))
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ ((struct bfd_link_info *) info)->flags |= DF_TEXTREL;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ /* Not an error, just cut short the traversal. */
|
|
|
881b8e |
+ return FALSE;
|
|
|
881b8e |
}
|
|
|
881b8e |
return TRUE;
|
|
|
881b8e |
}
|
|
|
881b8e |
@@ -9127,7 +9493,7 @@ readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|
|
881b8e |
/* Set the sizes of the dynamic sections. */
|
|
|
881b8e |
|
|
|
881b8e |
static bfd_boolean
|
|
|
881b8e |
-ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
881b8e |
+ppc64_elf_size_dynamic_sections (bfd *output_bfd,
|
|
|
881b8e |
struct bfd_link_info *info)
|
|
|
881b8e |
{
|
|
|
881b8e |
struct ppc_link_hash_table *htab;
|
|
|
881b8e |
@@ -9258,7 +9624,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
881b8e |
{
|
|
|
881b8e |
s = htab->iplt;
|
|
|
881b8e |
ent->plt.offset = s->size;
|
|
|
881b8e |
- s->size += PLT_ENTRY_SIZE;
|
|
|
881b8e |
+ s->size += PLT_ENTRY_SIZE (htab);
|
|
|
881b8e |
|
|
|
881b8e |
htab->reliplt->size += sizeof (Elf64_External_Rela);
|
|
|
881b8e |
}
|
|
|
881b8e |
@@ -9270,6 +9636,12 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
881b8e |
/* Allocate global sym .plt and .got entries, and space for global
|
|
|
881b8e |
sym dynamic relocs. */
|
|
|
881b8e |
elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
|
|
|
881b8e |
+ /* Stash the end of glink branch table. */
|
|
|
881b8e |
+ if (htab->glink != NULL)
|
|
|
881b8e |
+ htab->glink->rawsize = htab->glink->size;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (!htab->opd_abi && !info->shared)
|
|
|
881b8e |
+ elf_link_hash_traverse (&htab->elf, size_global_entry_stubs, info);
|
|
|
881b8e |
|
|
|
881b8e |
first_tlsld = NULL;
|
|
|
881b8e |
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
|
|
|
881b8e |
@@ -9415,6 +9787,8 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
881b8e |
|
|
|
881b8e |
if (htab->elf.dynamic_sections_created)
|
|
|
881b8e |
{
|
|
|
881b8e |
+ bfd_boolean tls_opt;
|
|
|
881b8e |
+
|
|
|
881b8e |
/* Add some entries to the .dynamic section. We fill in the
|
|
|
881b8e |
values later, in ppc64_elf_finish_dynamic_sections, but we
|
|
|
881b8e |
must add the entries now so that we get the correct size for
|
|
|
881b8e |
@@ -9439,18 +9813,21 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
881b8e |
return FALSE;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
- if (NO_OPD_RELOCS)
|
|
|
881b8e |
+ if (NO_OPD_RELOCS && abiversion (output_bfd) <= 1)
|
|
|
881b8e |
{
|
|
|
881b8e |
if (!add_dynamic_entry (DT_PPC64_OPD, 0)
|
|
|
881b8e |
|| !add_dynamic_entry (DT_PPC64_OPDSZ, 0))
|
|
|
881b8e |
return FALSE;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
- if (!htab->no_tls_get_addr_opt
|
|
|
881b8e |
- && htab->tls_get_addr_fd != NULL
|
|
|
881b8e |
- && htab->tls_get_addr_fd->elf.plt.plist != NULL
|
|
|
881b8e |
- && !add_dynamic_entry (DT_PPC64_TLSOPT, 0))
|
|
|
881b8e |
- return FALSE;
|
|
|
881b8e |
+ tls_opt = (!htab->no_tls_get_addr_opt
|
|
|
881b8e |
+ && htab->tls_get_addr_fd != NULL
|
|
|
881b8e |
+ && htab->tls_get_addr_fd->elf.plt.plist != NULL);
|
|
|
881b8e |
+ if (tls_opt || !htab->opd_abi)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ if (!add_dynamic_entry (DT_PPC64_OPT, tls_opt ? PPC64_OPT_TLS : 0))
|
|
|
881b8e |
+ return FALSE;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
|
|
|
881b8e |
if (relocs)
|
|
|
881b8e |
{
|
|
|
881b8e |
@@ -9462,7 +9839,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
881b8e |
/* If any dynamic relocs apply to a read-only section,
|
|
|
881b8e |
then we need a DT_TEXTREL entry. */
|
|
|
881b8e |
if ((info->flags & DF_TEXTREL) == 0)
|
|
|
881b8e |
- elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
|
|
|
881b8e |
+ elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
|
|
|
881b8e |
|
|
|
881b8e |
if ((info->flags & DF_TEXTREL) != 0)
|
|
|
881b8e |
{
|
|
|
881b8e |
@@ -9476,6 +9853,19 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
881b8e |
return TRUE;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
+/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
|
|
|
881b8e |
+
|
|
|
881b8e |
+static bfd_boolean
|
|
|
881b8e |
+ppc64_elf_hash_symbol (struct elf_link_hash_entry *h)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ if (h->plt.plist != NULL
|
|
|
881b8e |
+ && !h->def_regular
|
|
|
881b8e |
+ && !h->pointer_equality_needed)
|
|
|
881b8e |
+ return FALSE;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ return _bfd_elf_hash_symbol (h);
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
/* Determine the type of stub needed, if any, for a call. */
|
|
|
881b8e |
|
|
|
881b8e |
static inline enum ppc_stub_type
|
|
|
881b8e |
@@ -9483,7 +9873,8 @@ ppc_type_of_stub (asection *input_sec,
|
|
|
881b8e |
const Elf_Internal_Rela *rel,
|
|
|
881b8e |
struct ppc_link_hash_entry **hash,
|
|
|
881b8e |
struct plt_entry **plt_ent,
|
|
|
881b8e |
- bfd_vma destination)
|
|
|
881b8e |
+ bfd_vma destination,
|
|
|
881b8e |
+ unsigned long local_off)
|
|
|
881b8e |
{
|
|
|
881b8e |
struct ppc_link_hash_entry *h = *hash;
|
|
|
881b8e |
bfd_vma location;
|
|
|
881b8e |
@@ -9552,7 +9943,7 @@ ppc_type_of_stub (asection *input_sec,
|
|
|
881b8e |
if (r_type != R_PPC64_REL24)
|
|
|
881b8e |
max_branch_offset = 1 << 15;
|
|
|
881b8e |
|
|
|
881b8e |
- if (branch_offset + max_branch_offset >= 2 * max_branch_offset)
|
|
|
881b8e |
+ if (branch_offset + max_branch_offset >= 2 * max_branch_offset - local_off)
|
|
|
881b8e |
/* We need a stub. Figure out whether a long_branch or plt_branch
|
|
|
881b8e |
is needed later. */
|
|
|
881b8e |
return ppc_stub_long_branch;
|
|
|
881b8e |
@@ -9569,9 +9960,9 @@ ppc_type_of_stub (asection *input_sec,
|
|
|
881b8e |
the appropriate glink entry if so.
|
|
|
881b8e |
|
|
|
881b8e |
. fake dep barrier compare
|
|
|
881b8e |
- . ld 11,xxx(2) ld 11,xxx(2)
|
|
|
881b8e |
- . mtctr 11 mtctr 11
|
|
|
881b8e |
- . xor 11,11,11 ld 2,xxx+8(2)
|
|
|
881b8e |
+ . ld 12,xxx(2) ld 12,xxx(2)
|
|
|
881b8e |
+ . mtctr 12 mtctr 12
|
|
|
881b8e |
+ . xor 11,12,12 ld 2,xxx+8(2)
|
|
|
881b8e |
. add 2,2,11 cmpldi 2,0
|
|
|
881b8e |
. ld 2,xxx+8(2) bnectr+
|
|
|
881b8e |
. bctr b <glink_entry>
|
|
|
881b8e |
@@ -9591,19 +9982,23 @@ plt_stub_size (struct ppc_link_hash_table *htab,
|
|
|
881b8e |
struct ppc_stub_hash_entry *stub_entry,
|
|
|
881b8e |
bfd_vma off)
|
|
|
881b8e |
{
|
|
|
881b8e |
- unsigned size = PLT_CALL_STUB_SIZE;
|
|
|
881b8e |
-
|
|
|
881b8e |
- if (!(ALWAYS_EMIT_R2SAVE
|
|
|
881b8e |
- || stub_entry->stub_type == ppc_stub_plt_call_r2save))
|
|
|
881b8e |
- size -= 4;
|
|
|
881b8e |
- if (!htab->plt_static_chain)
|
|
|
881b8e |
- size -= 4;
|
|
|
881b8e |
- if (htab->plt_thread_safe)
|
|
|
881b8e |
- size += 8;
|
|
|
881b8e |
- if (PPC_HA (off) == 0)
|
|
|
881b8e |
- size -= 4;
|
|
|
881b8e |
- if (PPC_HA (off + 8 + 8 * htab->plt_static_chain) != PPC_HA (off))
|
|
|
881b8e |
+ unsigned size = 12;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (ALWAYS_EMIT_R2SAVE
|
|
|
881b8e |
+ || stub_entry->stub_type == ppc_stub_plt_call_r2save)
|
|
|
881b8e |
+ size += 4;
|
|
|
881b8e |
+ if (PPC_HA (off) != 0)
|
|
|
881b8e |
size += 4;
|
|
|
881b8e |
+ if (htab->opd_abi)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ size += 4;
|
|
|
881b8e |
+ if (htab->plt_static_chain)
|
|
|
881b8e |
+ size += 4;
|
|
|
881b8e |
+ if (htab->plt_thread_safe)
|
|
|
881b8e |
+ size += 8;
|
|
|
881b8e |
+ if (PPC_HA (off + 8 + 8 * htab->plt_static_chain) != PPC_HA (off))
|
|
|
881b8e |
+ size += 4;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
if (stub_entry->h != NULL
|
|
|
881b8e |
&& (stub_entry->h == htab->tls_get_addr_fd
|
|
|
881b8e |
|| stub_entry->h == htab->tls_get_addr)
|
|
|
881b8e |
@@ -9637,12 +10032,14 @@ build_plt_stub (struct ppc_link_hash_table *htab,
|
|
|
881b8e |
bfd_byte *p, bfd_vma offset, Elf_Internal_Rela *r)
|
|
|
881b8e |
{
|
|
|
881b8e |
bfd *obfd = htab->stub_bfd;
|
|
|
881b8e |
+ bfd_boolean plt_load_toc = htab->opd_abi;
|
|
|
881b8e |
bfd_boolean plt_static_chain = htab->plt_static_chain;
|
|
|
881b8e |
bfd_boolean plt_thread_safe = htab->plt_thread_safe;
|
|
|
881b8e |
bfd_boolean use_fake_dep = plt_thread_safe;
|
|
|
881b8e |
bfd_vma cmp_branch_off = 0;
|
|
|
881b8e |
|
|
|
881b8e |
if (!ALWAYS_USE_FAKE_DEP
|
|
|
881b8e |
+ && plt_load_toc
|
|
|
881b8e |
&& plt_thread_safe
|
|
|
881b8e |
&& !(stub_entry->h != NULL
|
|
|
881b8e |
&& (stub_entry->h == htab->tls_get_addr_fd
|
|
|
881b8e |
@@ -9650,7 +10047,8 @@ build_plt_stub (struct ppc_link_hash_table *htab,
|
|
|
881b8e |
&& !htab->no_tls_get_addr_opt))
|
|
|
881b8e |
{
|
|
|
881b8e |
bfd_vma pltoff = stub_entry->plt_ent->plt.offset & ~1;
|
|
|
881b8e |
- bfd_vma pltindex = (pltoff - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE;
|
|
|
881b8e |
+ bfd_vma pltindex = ((pltoff - PLT_INITIAL_ENTRY_SIZE (htab))
|
|
|
881b8e |
+ / PLT_ENTRY_SIZE (htab));
|
|
|
881b8e |
bfd_vma glinkoff = GLINK_CALL_STUB_SIZE + pltindex * 8;
|
|
|
881b8e |
bfd_vma to, from;
|
|
|
881b8e |
|
|
|
881b8e |
@@ -9684,44 +10082,51 @@ build_plt_stub (struct ppc_link_hash_table *htab,
|
|
|
881b8e |
r[1].r_offset = r[0].r_offset + 4;
|
|
|
881b8e |
r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
|
|
|
881b8e |
r[1].r_addend = r[0].r_addend;
|
|
|
881b8e |
- if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
|
|
|
881b8e |
- {
|
|
|
881b8e |
- r[2].r_offset = r[1].r_offset + 4;
|
|
|
881b8e |
- r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO);
|
|
|
881b8e |
- r[2].r_addend = r[0].r_addend;
|
|
|
881b8e |
- }
|
|
|
881b8e |
- else
|
|
|
881b8e |
+ if (plt_load_toc)
|
|
|
881b8e |
{
|
|
|
881b8e |
- r[2].r_offset = r[1].r_offset + 8 + 8 * use_fake_dep;
|
|
|
881b8e |
- r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
|
|
|
881b8e |
- r[2].r_addend = r[0].r_addend + 8;
|
|
|
881b8e |
- if (plt_static_chain)
|
|
|
881b8e |
+ if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
|
|
|
881b8e |
{
|
|
|
881b8e |
- r[3].r_offset = r[2].r_offset + 4;
|
|
|
881b8e |
- r[3].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
|
|
|
881b8e |
- r[3].r_addend = r[0].r_addend + 16;
|
|
|
881b8e |
+ r[2].r_offset = r[1].r_offset + 4;
|
|
|
881b8e |
+ r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO);
|
|
|
881b8e |
+ r[2].r_addend = r[0].r_addend;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ else
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ r[2].r_offset = r[1].r_offset + 8 + 8 * use_fake_dep;
|
|
|
881b8e |
+ r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
|
|
|
881b8e |
+ r[2].r_addend = r[0].r_addend + 8;
|
|
|
881b8e |
+ if (plt_static_chain)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ r[3].r_offset = r[2].r_offset + 4;
|
|
|
881b8e |
+ r[3].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
|
|
|
881b8e |
+ r[3].r_addend = r[0].r_addend + 16;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
}
|
|
|
881b8e |
}
|
|
|
881b8e |
}
|
|
|
881b8e |
if (ALWAYS_EMIT_R2SAVE
|
|
|
881b8e |
|| stub_entry->stub_type == ppc_stub_plt_call_r2save)
|
|
|
881b8e |
- bfd_put_32 (obfd, STD_R2_40R1, p), p += 4;
|
|
|
881b8e |
- bfd_put_32 (obfd, ADDIS_R12_R2 | PPC_HA (offset), p), p += 4;
|
|
|
881b8e |
- bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset), p), p += 4;
|
|
|
881b8e |
- if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
|
|
|
881b8e |
+ bfd_put_32 (obfd, STD_R2_0R1 + STK_TOC (htab), p), p += 4;
|
|
|
881b8e |
+ bfd_put_32 (obfd, ADDIS_R11_R2 | PPC_HA (offset), p), p += 4;
|
|
|
881b8e |
+ bfd_put_32 (obfd, LD_R12_0R11 | PPC_LO (offset), p), p += 4;
|
|
|
881b8e |
+ if (plt_load_toc
|
|
|
881b8e |
+ && PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
|
|
|
881b8e |
{
|
|
|
881b8e |
- bfd_put_32 (obfd, ADDI_R12_R12 | PPC_LO (offset), p), p += 4;
|
|
|
881b8e |
+ bfd_put_32 (obfd, ADDI_R11_R11 | PPC_LO (offset), p), p += 4;
|
|
|
881b8e |
offset = 0;
|
|
|
881b8e |
}
|
|
|
881b8e |
- bfd_put_32 (obfd, MTCTR_R11, p), p += 4;
|
|
|
881b8e |
- if (use_fake_dep)
|
|
|
881b8e |
+ bfd_put_32 (obfd, MTCTR_R12, p), p += 4;
|
|
|
881b8e |
+ if (plt_load_toc)
|
|
|
881b8e |
{
|
|
|
881b8e |
- bfd_put_32 (obfd, XOR_R11_R11_R11, p), p += 4;
|
|
|
881b8e |
- bfd_put_32 (obfd, ADD_R12_R12_R11, p), p += 4;
|
|
|
881b8e |
+ if (use_fake_dep)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ bfd_put_32 (obfd, XOR_R2_R12_R12, p), p += 4;
|
|
|
881b8e |
+ bfd_put_32 (obfd, ADD_R11_R11_R2, p), p += 4;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ bfd_put_32 (obfd, LD_R2_0R11 | PPC_LO (offset + 8), p), p += 4;
|
|
|
881b8e |
+ if (plt_static_chain)
|
|
|
881b8e |
+ bfd_put_32 (obfd, LD_R11_0R11 | PPC_LO (offset + 16), p), p += 4;
|
|
|
881b8e |
}
|
|
|
881b8e |
- bfd_put_32 (obfd, LD_R2_0R12 | PPC_LO (offset + 8), p), p += 4;
|
|
|
881b8e |
- if (plt_static_chain)
|
|
|
881b8e |
- bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset + 16), p), p += 4;
|
|
|
881b8e |
}
|
|
|
881b8e |
else
|
|
|
881b8e |
{
|
|
|
881b8e |
@@ -9731,45 +10136,52 @@ build_plt_stub (struct ppc_link_hash_table *htab,
|
|
|
881b8e |
|| stub_entry->stub_type == ppc_stub_plt_call_r2save)
|
|
|
881b8e |
r[0].r_offset += 4;
|
|
|
881b8e |
r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
|
|
|
881b8e |
- if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
|
|
|
881b8e |
+ if (plt_load_toc)
|
|
|
881b8e |
{
|
|
|
881b8e |
- r[1].r_offset = r[0].r_offset + 4;
|
|
|
881b8e |
- r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16);
|
|
|
881b8e |
- r[1].r_addend = r[0].r_addend;
|
|
|
881b8e |
- }
|
|
|
881b8e |
- else
|
|
|
881b8e |
- {
|
|
|
881b8e |
- r[1].r_offset = r[0].r_offset + 8 + 8 * use_fake_dep;
|
|
|
881b8e |
- r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
|
|
|
881b8e |
- r[1].r_addend = r[0].r_addend + 8 + 8 * plt_static_chain;
|
|
|
881b8e |
- if (plt_static_chain)
|
|
|
881b8e |
+ if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
|
|
|
881b8e |
{
|
|
|
881b8e |
- r[2].r_offset = r[1].r_offset + 4;
|
|
|
881b8e |
- r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
|
|
|
881b8e |
- r[2].r_addend = r[0].r_addend + 8;
|
|
|
881b8e |
+ r[1].r_offset = r[0].r_offset + 4;
|
|
|
881b8e |
+ r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16);
|
|
|
881b8e |
+ r[1].r_addend = r[0].r_addend;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ else
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ r[1].r_offset = r[0].r_offset + 8 + 8 * use_fake_dep;
|
|
|
881b8e |
+ r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
|
|
|
881b8e |
+ r[1].r_addend = r[0].r_addend + 8 + 8 * plt_static_chain;
|
|
|
881b8e |
+ if (plt_static_chain)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ r[2].r_offset = r[1].r_offset + 4;
|
|
|
881b8e |
+ r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
|
|
|
881b8e |
+ r[2].r_addend = r[0].r_addend + 8;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
}
|
|
|
881b8e |
}
|
|
|
881b8e |
}
|
|
|
881b8e |
if (ALWAYS_EMIT_R2SAVE
|
|
|
881b8e |
|| stub_entry->stub_type == ppc_stub_plt_call_r2save)
|
|
|
881b8e |
- bfd_put_32 (obfd, STD_R2_40R1, p), p += 4;
|
|
|
881b8e |
- bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset), p), p += 4;
|
|
|
881b8e |
- if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
|
|
|
881b8e |
+ bfd_put_32 (obfd, STD_R2_0R1 + STK_TOC (htab), p), p += 4;
|
|
|
881b8e |
+ bfd_put_32 (obfd, LD_R12_0R2 | PPC_LO (offset), p), p += 4;
|
|
|
881b8e |
+ if (plt_load_toc
|
|
|
881b8e |
+ && PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
|
|
|
881b8e |
{
|
|
|
881b8e |
bfd_put_32 (obfd, ADDI_R2_R2 | PPC_LO (offset), p), p += 4;
|
|
|
881b8e |
offset = 0;
|
|
|
881b8e |
}
|
|
|
881b8e |
- bfd_put_32 (obfd, MTCTR_R11, p), p += 4;
|
|
|
881b8e |
- if (use_fake_dep)
|
|
|
881b8e |
+ bfd_put_32 (obfd, MTCTR_R12, p), p += 4;
|
|
|
881b8e |
+ if (plt_load_toc)
|
|
|
881b8e |
{
|
|
|
881b8e |
- bfd_put_32 (obfd, XOR_R11_R11_R11, p), p += 4;
|
|
|
881b8e |
- bfd_put_32 (obfd, ADD_R2_R2_R11, p), p += 4;
|
|
|
881b8e |
+ if (use_fake_dep)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ bfd_put_32 (obfd, XOR_R11_R12_R12, p), p += 4;
|
|
|
881b8e |
+ bfd_put_32 (obfd, ADD_R2_R2_R11, p), p += 4;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ if (plt_static_chain)
|
|
|
881b8e |
+ bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset + 16), p), p += 4;
|
|
|
881b8e |
+ bfd_put_32 (obfd, LD_R2_0R2 | PPC_LO (offset + 8), p), p += 4;
|
|
|
881b8e |
}
|
|
|
881b8e |
- if (plt_static_chain)
|
|
|
881b8e |
- bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset + 16), p), p += 4;
|
|
|
881b8e |
- bfd_put_32 (obfd, LD_R2_0R2 | PPC_LO (offset + 8), p), p += 4;
|
|
|
881b8e |
}
|
|
|
881b8e |
- if (plt_thread_safe && !use_fake_dep)
|
|
|
881b8e |
+ if (plt_load_toc && plt_thread_safe && !use_fake_dep)
|
|
|
881b8e |
{
|
|
|
881b8e |
bfd_put_32 (obfd, CMPLDI_R2_0, p), p += 4;
|
|
|
881b8e |
bfd_put_32 (obfd, BNECTR_P4, p), p += 4;
|
|
|
881b8e |
@@ -9789,11 +10201,9 @@ build_plt_stub (struct ppc_link_hash_table *htab,
|
|
|
881b8e |
#define ADD_R3_R12_R13 0x7c6c6a14
|
|
|
881b8e |
#define BEQLR 0x4d820020
|
|
|
881b8e |
#define MR_R3_R0 0x7c030378
|
|
|
881b8e |
-#define MFLR_R11 0x7d6802a6
|
|
|
881b8e |
#define STD_R11_0R1 0xf9610000
|
|
|
881b8e |
#define BCTRL 0x4e800421
|
|
|
881b8e |
#define LD_R11_0R1 0xe9610000
|
|
|
881b8e |
-#define LD_R2_0R1 0xe8410000
|
|
|
881b8e |
#define MTLR_R11 0x7d6803a6
|
|
|
881b8e |
|
|
|
881b8e |
static inline bfd_byte *
|
|
|
881b8e |
@@ -9811,15 +10221,15 @@ build_tls_get_addr_stub (struct ppc_link_hash_table *htab,
|
|
|
881b8e |
bfd_put_32 (obfd, BEQLR, p), p += 4;
|
|
|
881b8e |
bfd_put_32 (obfd, MR_R3_R0, p), p += 4;
|
|
|
881b8e |
bfd_put_32 (obfd, MFLR_R11, p), p += 4;
|
|
|
881b8e |
- bfd_put_32 (obfd, STD_R11_0R1 + 32, p), p += 4;
|
|
|
881b8e |
+ bfd_put_32 (obfd, STD_R11_0R1 + STK_LINKER (htab), p), p += 4;
|
|
|
881b8e |
|
|
|
881b8e |
if (r != NULL)
|
|
|
881b8e |
r[0].r_offset += 9 * 4;
|
|
|
881b8e |
p = build_plt_stub (htab, stub_entry, p, offset, r);
|
|
|
881b8e |
bfd_put_32 (obfd, BCTRL, p - 4);
|
|
|
881b8e |
|
|
|
881b8e |
- bfd_put_32 (obfd, LD_R11_0R1 + 32, p), p += 4;
|
|
|
881b8e |
- bfd_put_32 (obfd, LD_R2_0R1 + 40, p), p += 4;
|
|
|
881b8e |
+ bfd_put_32 (obfd, LD_R11_0R1 + STK_LINKER (htab), p), p += 4;
|
|
|
881b8e |
+ bfd_put_32 (obfd, LD_R2_0R1 + STK_TOC (htab), p), p += 4;
|
|
|
881b8e |
bfd_put_32 (obfd, MTLR_R11, p), p += 4;
|
|
|
881b8e |
bfd_put_32 (obfd, BLR, p), p += 4;
|
|
|
881b8e |
|
|
|
881b8e |
@@ -9868,6 +10278,8 @@ get_r2off (struct bfd_link_info *info,
|
|
|
881b8e |
/* Support linking -R objects. Get the toc pointer from the
|
|
|
881b8e |
opd entry. */
|
|
|
881b8e |
char buf[8];
|
|
|
881b8e |
+ if (!htab->opd_abi)
|
|
|
881b8e |
+ return r2off;
|
|
|
881b8e |
asection *opd = stub_entry->h->elf.root.u.def.section;
|
|
|
881b8e |
bfd_vma opd_off = stub_entry->h->elf.root.u.def.value;
|
|
|
881b8e |
|
|
|
881b8e |
@@ -9920,9 +10332,11 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|
|
881b8e |
case ppc_stub_long_branch:
|
|
|
881b8e |
case ppc_stub_long_branch_r2off:
|
|
|
881b8e |
/* Branches are relative. This is where we are going to. */
|
|
|
881b8e |
- off = dest = (stub_entry->target_value
|
|
|
881b8e |
- + stub_entry->target_section->output_offset
|
|
|
881b8e |
- + stub_entry->target_section->output_section->vma);
|
|
|
881b8e |
+ dest = (stub_entry->target_value
|
|
|
881b8e |
+ + stub_entry->target_section->output_offset
|
|
|
881b8e |
+ + stub_entry->target_section->output_section->vma);
|
|
|
881b8e |
+ dest += PPC64_LOCAL_ENTRY_OFFSET (stub_entry->other);
|
|
|
881b8e |
+ off = dest;
|
|
|
881b8e |
|
|
|
881b8e |
/* And this is where we are coming from. */
|
|
|
881b8e |
off -= (stub_entry->stub_offset
|
|
|
881b8e |
@@ -9939,7 +10353,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|
|
881b8e |
htab->stub_error = TRUE;
|
|
|
881b8e |
return FALSE;
|
|
|
881b8e |
}
|
|
|
881b8e |
- bfd_put_32 (htab->stub_bfd, STD_R2_40R1, loc);
|
|
|
881b8e |
+ bfd_put_32 (htab->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
|
|
|
881b8e |
loc += 4;
|
|
|
881b8e |
size = 12;
|
|
|
881b8e |
if (PPC_HA (r2off) != 0)
|
|
|
881b8e |
@@ -10025,6 +10439,8 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|
|
881b8e |
dest = (stub_entry->target_value
|
|
|
881b8e |
+ stub_entry->target_section->output_offset
|
|
|
881b8e |
+ stub_entry->target_section->output_section->vma);
|
|
|
881b8e |
+ if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
|
|
|
881b8e |
+ dest += PPC64_LOCAL_ENTRY_OFFSET (stub_entry->other);
|
|
|
881b8e |
|
|
|
881b8e |
bfd_put_64 (htab->brlt->owner, dest,
|
|
|
881b8e |
htab->brlt->contents + br_entry->offset);
|
|
|
881b8e |
@@ -10093,7 +10509,8 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|
|
881b8e |
r[0].r_offset = loc - stub_entry->stub_sec->contents;
|
|
|
881b8e |
if (bfd_big_endian (info->output_bfd))
|
|
|
881b8e |
r[0].r_offset += 2;
|
|
|
881b8e |
- if (stub_entry->stub_type == ppc_stub_plt_branch_r2off)
|
|
|
881b8e |
+ if (stub_entry->stub_type == ppc_stub_plt_branch_r2off
|
|
|
881b8e |
+ && htab->opd_abi)
|
|
|
881b8e |
r[0].r_offset += 4;
|
|
|
881b8e |
r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
|
|
|
881b8e |
r[0].r_addend = dest;
|
|
|
881b8e |
@@ -10106,19 +10523,20 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|
|
881b8e |
}
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
- if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
|
|
|
881b8e |
+ if (stub_entry->stub_type != ppc_stub_plt_branch_r2off
|
|
|
881b8e |
+ || !htab->opd_abi)
|
|
|
881b8e |
{
|
|
|
881b8e |
if (PPC_HA (off) != 0)
|
|
|
881b8e |
{
|
|
|
881b8e |
size = 16;
|
|
|
881b8e |
- bfd_put_32 (htab->stub_bfd, ADDIS_R12_R2 | PPC_HA (off), loc);
|
|
|
881b8e |
+ bfd_put_32 (htab->stub_bfd, ADDIS_R11_R2 | PPC_HA (off), loc);
|
|
|
881b8e |
loc += 4;
|
|
|
881b8e |
- bfd_put_32 (htab->stub_bfd, LD_R11_0R12 | PPC_LO (off), loc);
|
|
|
881b8e |
+ bfd_put_32 (htab->stub_bfd, LD_R12_0R11 | PPC_LO (off), loc);
|
|
|
881b8e |
}
|
|
|
881b8e |
else
|
|
|
881b8e |
{
|
|
|
881b8e |
size = 12;
|
|
|
881b8e |
- bfd_put_32 (htab->stub_bfd, LD_R11_0R2 | PPC_LO (off), loc);
|
|
|
881b8e |
+ bfd_put_32 (htab->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc);
|
|
|
881b8e |
}
|
|
|
881b8e |
}
|
|
|
881b8e |
else
|
|
|
881b8e |
@@ -10131,20 +10549,20 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|
|
881b8e |
return FALSE;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
- bfd_put_32 (htab->stub_bfd, STD_R2_40R1, loc);
|
|
|
881b8e |
+ bfd_put_32 (htab->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
|
|
|
881b8e |
loc += 4;
|
|
|
881b8e |
size = 20;
|
|
|
881b8e |
if (PPC_HA (off) != 0)
|
|
|
881b8e |
{
|
|
|
881b8e |
size += 4;
|
|
|
881b8e |
- bfd_put_32 (htab->stub_bfd, ADDIS_R12_R2 | PPC_HA (off), loc);
|
|
|
881b8e |
+ bfd_put_32 (htab->stub_bfd, ADDIS_R11_R2 | PPC_HA (off), loc);
|
|
|
881b8e |
loc += 4;
|
|
|
881b8e |
- bfd_put_32 (htab->stub_bfd, LD_R11_0R12 | PPC_LO (off), loc);
|
|
|
881b8e |
+ bfd_put_32 (htab->stub_bfd, LD_R12_0R11 | PPC_LO (off), loc);
|
|
|
881b8e |
loc += 4;
|
|
|
881b8e |
}
|
|
|
881b8e |
else
|
|
|
881b8e |
{
|
|
|
881b8e |
- bfd_put_32 (htab->stub_bfd, LD_R11_0R2 | PPC_LO (off), loc);
|
|
|
881b8e |
+ bfd_put_32 (htab->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc);
|
|
|
881b8e |
loc += 4;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
@@ -10157,7 +10575,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|
|
881b8e |
bfd_put_32 (htab->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
|
|
|
881b8e |
}
|
|
|
881b8e |
loc += 4;
|
|
|
881b8e |
- bfd_put_32 (htab->stub_bfd, MTCTR_R11, loc);
|
|
|
881b8e |
+ bfd_put_32 (htab->stub_bfd, MTCTR_R12, loc);
|
|
|
881b8e |
loc += 4;
|
|
|
881b8e |
bfd_put_32 (htab->stub_bfd, BCTR, loc);
|
|
|
881b8e |
break;
|
|
|
881b8e |
@@ -10202,7 +10620,10 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|
|
881b8e |
bfd_byte *rl;
|
|
|
881b8e |
|
|
|
881b8e |
rela.r_offset = dest;
|
|
|
881b8e |
- rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
|
|
|
881b8e |
+ if (htab->opd_abi)
|
|
|
881b8e |
+ rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
|
|
|
881b8e |
+ else
|
|
|
881b8e |
+ rela.r_info = ELF64_R_INFO (0, R_PPC64_IRELATIVE);
|
|
|
881b8e |
rela.r_addend = (stub_entry->target_value
|
|
|
881b8e |
+ stub_entry->target_section->output_offset
|
|
|
881b8e |
+ stub_entry->target_section->output_section->vma);
|
|
|
881b8e |
@@ -10354,10 +10775,11 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|
|
881b8e |
if (info->emitrelocations)
|
|
|
881b8e |
{
|
|
|
881b8e |
stub_entry->stub_sec->reloc_count
|
|
|
881b8e |
- += (2
|
|
|
881b8e |
- + (PPC_HA (off) != 0)
|
|
|
881b8e |
- + (htab->plt_static_chain
|
|
|
881b8e |
- && PPC_HA (off + 16) == PPC_HA (off)));
|
|
|
881b8e |
+ += ((PPC_HA (off) != 0)
|
|
|
881b8e |
+ + (htab->opd_abi
|
|
|
881b8e |
+ ? 2 + (htab->plt_static_chain
|
|
|
881b8e |
+ && PPC_HA (off + 16) == PPC_HA (off))
|
|
|
881b8e |
+ : 1));
|
|
|
881b8e |
stub_entry->stub_sec->flags |= SEC_RELOC;
|
|
|
881b8e |
}
|
|
|
881b8e |
}
|
|
|
881b8e |
@@ -10366,6 +10788,7 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|
|
881b8e |
/* ppc_stub_long_branch or ppc_stub_plt_branch, or their r2off
|
|
|
881b8e |
variants. */
|
|
|
881b8e |
bfd_vma r2off = 0;
|
|
|
881b8e |
+ bfd_vma local_off = 0;
|
|
|
881b8e |
|
|
|
881b8e |
off = (stub_entry->target_value
|
|
|
881b8e |
+ stub_entry->target_section->output_offset
|
|
|
881b8e |
@@ -10383,7 +10806,7 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|
|
881b8e |
if (stub_entry->stub_type == ppc_stub_long_branch_r2off)
|
|
|
881b8e |
{
|
|
|
881b8e |
r2off = get_r2off (info, stub_entry);
|
|
|
881b8e |
- if (r2off == 0)
|
|
|
881b8e |
+ if (r2off == 0 && htab->opd_abi)
|
|
|
881b8e |
{
|
|
|
881b8e |
htab->stub_error = TRUE;
|
|
|
881b8e |
return FALSE;
|
|
|
881b8e |
@@ -10394,8 +10817,13 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|
|
881b8e |
off -= size - 4;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
- /* If the branch offset if too big, use a ppc_stub_plt_branch. */
|
|
|
881b8e |
- if (off + (1 << 25) >= (bfd_vma) (1 << 26))
|
|
|
881b8e |
+ local_off = PPC64_LOCAL_ENTRY_OFFSET (stub_entry->other);
|
|
|
881b8e |
+
|
|
|
881b8e |
+ /* If the branch offset if too big, use a ppc_stub_plt_branch.
|
|
|
881b8e |
+ Do the same for -R objects without function descriptors. */
|
|
|
881b8e |
+ if (off + (1 << 25) >= (bfd_vma) (1 << 26) - local_off
|
|
|
881b8e |
+ || (stub_entry->stub_type == ppc_stub_long_branch_r2off
|
|
|
881b8e |
+ && r2off == 0))
|
|
|
881b8e |
{
|
|
|
881b8e |
struct ppc_branch_hash_entry *br_entry;
|
|
|
881b8e |
|
|
|
881b8e |
@@ -10438,7 +10866,8 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|
|
881b8e |
stub_entry->stub_sec->flags |= SEC_RELOC;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
- if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
|
|
|
881b8e |
+ if (stub_entry->stub_type != ppc_stub_plt_branch_r2off
|
|
|
881b8e |
+ || !htab->opd_abi)
|
|
|
881b8e |
{
|
|
|
881b8e |
size = 12;
|
|
|
881b8e |
if (PPC_HA (off) != 0)
|
|
|
881b8e |
@@ -10991,7 +11420,10 @@ toc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
|
|
|
881b8e |
need a plt_branch stub. A plt_branch stub uses r2. */
|
|
|
881b8e |
else if (dest - (isec->output_offset
|
|
|
881b8e |
+ isec->output_section->vma
|
|
|
881b8e |
- + rel->r_offset) + (1 << 25) >= (2 << 25))
|
|
|
881b8e |
+ + rel->r_offset) + (1 << 25)
|
|
|
881b8e |
+ >= (2u << 25) - PPC64_LOCAL_ENTRY_OFFSET (h
|
|
|
881b8e |
+ ? h->other
|
|
|
881b8e |
+ : sym->st_other))
|
|
|
881b8e |
{
|
|
|
881b8e |
ret = 1;
|
|
|
881b8e |
break;
|
|
|
881b8e |
@@ -11338,7 +11770,9 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
|
|
|
881b8e |
htab->plt_stub_align = plt_stub_align;
|
|
|
881b8e |
if (plt_thread_safe == -1 && !info->executable)
|
|
|
881b8e |
plt_thread_safe = 1;
|
|
|
881b8e |
- if (plt_thread_safe == -1)
|
|
|
881b8e |
+ if (!htab->opd_abi)
|
|
|
881b8e |
+ plt_thread_safe = 0;
|
|
|
881b8e |
+ else if (plt_thread_safe == -1)
|
|
|
881b8e |
{
|
|
|
881b8e |
static const char *const thread_starter[] =
|
|
|
881b8e |
{
|
|
|
881b8e |
@@ -11447,6 +11881,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
|
|
|
881b8e |
asection *sym_sec, *code_sec;
|
|
|
881b8e |
bfd_vma sym_value, code_value;
|
|
|
881b8e |
bfd_vma destination;
|
|
|
881b8e |
+ unsigned long local_off;
|
|
|
881b8e |
bfd_boolean ok_dest;
|
|
|
881b8e |
struct ppc_link_hash_entry *hash;
|
|
|
881b8e |
struct ppc_link_hash_entry *fdh;
|
|
|
881b8e |
@@ -11523,12 +11958,16 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
destination = 0;
|
|
|
881b8e |
+ local_off = 0;
|
|
|
881b8e |
if (ok_dest)
|
|
|
881b8e |
{
|
|
|
881b8e |
sym_value += irela->r_addend;
|
|
|
881b8e |
destination = (sym_value
|
|
|
881b8e |
+ sym_sec->output_offset
|
|
|
881b8e |
+ sym_sec->output_section->vma);
|
|
|
881b8e |
+ local_off = PPC64_LOCAL_ENTRY_OFFSET (hash
|
|
|
881b8e |
+ ? hash->elf.other
|
|
|
881b8e |
+ : sym->st_other);
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
code_sec = sym_sec;
|
|
|
881b8e |
@@ -11565,7 +12004,8 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
|
|
|
881b8e |
/* Determine what (if any) linker stub is needed. */
|
|
|
881b8e |
plt_ent = NULL;
|
|
|
881b8e |
stub_type = ppc_type_of_stub (section, irela, &hash,
|
|
|
881b8e |
- &plt_ent, destination);
|
|
|
881b8e |
+ &plt_ent, destination,
|
|
|
881b8e |
+ local_off);
|
|
|
881b8e |
|
|
|
881b8e |
if (stub_type != ppc_stub_plt_call)
|
|
|
881b8e |
{
|
|
|
881b8e |
@@ -11828,6 +12268,72 @@ ppc64_elf_toc (bfd *obfd)
|
|
|
881b8e |
return TOCstart;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
+/* Called via elf_link_hash_traverse from ppc64_elf_build_stubs to
|
|
|
881b8e |
+ write out any global entry stubs. */
|
|
|
881b8e |
+
|
|
|
881b8e |
+static bfd_boolean
|
|
|
881b8e |
+build_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ struct bfd_link_info *info;
|
|
|
881b8e |
+ struct ppc_link_hash_table *htab;
|
|
|
881b8e |
+ struct plt_entry *pent;
|
|
|
881b8e |
+ asection *s;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (h->root.type == bfd_link_hash_indirect)
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (!h->pointer_equality_needed)
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (h->def_regular)
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ info = inf;
|
|
|
881b8e |
+ htab = ppc_hash_table (info);
|
|
|
881b8e |
+ if (htab == NULL)
|
|
|
881b8e |
+ return FALSE;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ s = htab->glink;
|
|
|
881b8e |
+ for (pent = h->plt.plist; pent != NULL; pent = pent->next)
|
|
|
881b8e |
+ if (pent->plt.offset != (bfd_vma) -1
|
|
|
881b8e |
+ && pent->addend == 0)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ bfd_byte *p;
|
|
|
881b8e |
+ asection *plt;
|
|
|
881b8e |
+ bfd_vma off;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ p = s->contents + h->root.u.def.value;
|
|
|
881b8e |
+ plt = htab->plt;
|
|
|
881b8e |
+ if (!htab->elf.dynamic_sections_created
|
|
|
881b8e |
+ || h->dynindx == -1)
|
|
|
881b8e |
+ plt = htab->iplt;
|
|
|
881b8e |
+ off = pent->plt.offset + plt->output_offset + plt->output_section->vma;
|
|
|
881b8e |
+ off -= h->root.u.def.value + s->output_offset + s->output_section->vma;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (off + 0x80008000 > 0xffffffff || (off & 3) != 0)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ info->callbacks->einfo
|
|
|
881b8e |
+ (_("%P: linkage table error against `%T'\n"),
|
|
|
881b8e |
+ h->root.root.string);
|
|
|
881b8e |
+ bfd_set_error (bfd_error_bad_value);
|
|
|
881b8e |
+ htab->stub_error = TRUE;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (PPC_HA (off) != 0)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ bfd_put_32 (s->owner, ADDIS_R12_R12 | PPC_HA (off), p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ bfd_put_32 (s->owner, LD_R12_0R12 | PPC_LO (off), p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (s->owner, MTCTR_R12, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (s->owner, BCTR, p);
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ return TRUE;
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
/* Build all the stubs associated with the current output file.
|
|
|
881b8e |
The stubs are kept in a hash table attached to the main linker
|
|
|
881b8e |
hash table. This function is called via gldelf64ppc_finish. */
|
|
|
881b8e |
@@ -11903,26 +12409,56 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
|
|
|
881b8e |
plt0 -= htab->glink->output_section->vma + htab->glink->output_offset;
|
|
|
881b8e |
bfd_put_64 (htab->glink->owner, plt0, p);
|
|
|
881b8e |
p += 8;
|
|
|
881b8e |
- bfd_put_32 (htab->glink->owner, MFLR_R12, p);
|
|
|
881b8e |
- p += 4;
|
|
|
881b8e |
- bfd_put_32 (htab->glink->owner, BCL_20_31, p);
|
|
|
881b8e |
- p += 4;
|
|
|
881b8e |
- bfd_put_32 (htab->glink->owner, MFLR_R11, p);
|
|
|
881b8e |
- p += 4;
|
|
|
881b8e |
- bfd_put_32 (htab->glink->owner, LD_R2_M16R11, p);
|
|
|
881b8e |
- p += 4;
|
|
|
881b8e |
- bfd_put_32 (htab->glink->owner, MTLR_R12, p);
|
|
|
881b8e |
- p += 4;
|
|
|
881b8e |
- bfd_put_32 (htab->glink->owner, ADD_R12_R2_R11, p);
|
|
|
881b8e |
- p += 4;
|
|
|
881b8e |
- bfd_put_32 (htab->glink->owner, LD_R11_0R12, p);
|
|
|
881b8e |
- p += 4;
|
|
|
881b8e |
- bfd_put_32 (htab->glink->owner, LD_R2_0R12 | 8, p);
|
|
|
881b8e |
- p += 4;
|
|
|
881b8e |
- bfd_put_32 (htab->glink->owner, MTCTR_R11, p);
|
|
|
881b8e |
- p += 4;
|
|
|
881b8e |
- bfd_put_32 (htab->glink->owner, LD_R11_0R12 | 16, p);
|
|
|
881b8e |
- p += 4;
|
|
|
881b8e |
+ if (htab->opd_abi)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, MFLR_R12, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, BCL_20_31, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, MFLR_R11, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, LD_R2_0R11 | (-16 & 0xfffc), p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, MTLR_R12, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, ADD_R11_R2_R11, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, LD_R12_0R11, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, LD_R2_0R11 | 8, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, MTCTR_R12, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, LD_R11_0R11 | 16, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ else
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, MFLR_R0, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, BCL_20_31, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, MFLR_R11, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, LD_R2_0R11 | (-16 & 0xfffc), p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, MTLR_R0, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, SUB_R12_R12_R11, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, ADD_R11_R2_R11, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, ADDI_R0_R12 | (-48 & 0xffff), p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, LD_R12_0R11, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, SRDI_R0_R0_2, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, MTCTR_R12, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, LD_R11_0R11 | 8, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
bfd_put_32 (htab->glink->owner, BCTR, p);
|
|
|
881b8e |
p += 4;
|
|
|
881b8e |
while (p - htab->glink->contents < GLINK_CALL_STUB_SIZE)
|
|
|
881b8e |
@@ -11933,26 +12469,33 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
|
|
|
881b8e |
|
|
|
881b8e |
/* Build the .glink lazy link call stubs. */
|
|
|
881b8e |
indx = 0;
|
|
|
881b8e |
- while (p < htab->glink->contents + htab->glink->size)
|
|
|
881b8e |
+ while (p < htab->glink->contents + htab->glink->rawsize)
|
|
|
881b8e |
{
|
|
|
881b8e |
- if (indx < 0x8000)
|
|
|
881b8e |
- {
|
|
|
881b8e |
- bfd_put_32 (htab->glink->owner, LI_R0_0 | indx, p);
|
|
|
881b8e |
- p += 4;
|
|
|
881b8e |
- }
|
|
|
881b8e |
- else
|
|
|
881b8e |
+ if (htab->opd_abi)
|
|
|
881b8e |
{
|
|
|
881b8e |
- bfd_put_32 (htab->glink->owner, LIS_R0_0 | PPC_HI (indx), p);
|
|
|
881b8e |
- p += 4;
|
|
|
881b8e |
- bfd_put_32 (htab->glink->owner, ORI_R0_R0_0 | PPC_LO (indx), p);
|
|
|
881b8e |
- p += 4;
|
|
|
881b8e |
+ if (indx < 0x8000)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, LI_R0_0 | indx, p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ else
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, LIS_R0_0 | PPC_HI (indx), p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ bfd_put_32 (htab->glink->owner, ORI_R0_R0_0 | PPC_LO (indx),
|
|
|
881b8e |
+ p);
|
|
|
881b8e |
+ p += 4;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
}
|
|
|
881b8e |
bfd_put_32 (htab->glink->owner,
|
|
|
881b8e |
B_DOT | ((htab->glink->contents - p + 8) & 0x3fffffc), p);
|
|
|
881b8e |
indx++;
|
|
|
881b8e |
p += 4;
|
|
|
881b8e |
}
|
|
|
881b8e |
- htab->glink->rawsize = p - htab->glink->contents;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ /* Build .glink global entry stubs. */
|
|
|
881b8e |
+ if (htab->glink->size > htab->glink->rawsize)
|
|
|
881b8e |
+ elf_link_hash_traverse (&htab->elf, build_global_entry_stubs, info);
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
if (htab->brlt->size != 0)
|
|
|
881b8e |
@@ -12056,7 +12599,7 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
|
|
|
881b8e |
bfd_put_32 (htab->elf.dynobj, val, p);
|
|
|
881b8e |
p += 4;
|
|
|
881b8e |
/* .glink size. */
|
|
|
881b8e |
- bfd_put_32 (htab->elf.dynobj, htab->glink->rawsize - 8, p);
|
|
|
881b8e |
+ bfd_put_32 (htab->elf.dynobj, htab->glink->size - 8, p);
|
|
|
881b8e |
p += 4;
|
|
|
881b8e |
/* Augmentation. */
|
|
|
881b8e |
p += 1;
|
|
|
881b8e |
@@ -12106,7 +12649,6 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
if (stub_sec != NULL
|
|
|
881b8e |
- || htab->glink->rawsize != htab->glink->size
|
|
|
881b8e |
|| (htab->glink_eh_frame != NULL
|
|
|
881b8e |
&& htab->glink_eh_frame->rawsize != htab->glink_eh_frame->size))
|
|
|
881b8e |
{
|
|
|
881b8e |
@@ -12849,6 +13391,39 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|
|
881b8e |
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
|
|
|
881b8e |
}
|
|
|
881b8e |
break;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ case R_PPC64_REL16_HA:
|
|
|
881b8e |
+ /* If we are generating a non-PIC executable, edit
|
|
|
881b8e |
+ . 0: addis 2,12,.TOC.-0b@ha
|
|
|
881b8e |
+ . addi 2,2,.TOC.-0b@l
|
|
|
881b8e |
+ used by ELFv2 global entry points to set up r2, to
|
|
|
881b8e |
+ . lis 2,.TOC.@ha
|
|
|
881b8e |
+ . addi 2,2,.TOC.@l
|
|
|
881b8e |
+ if .TOC. is in range. */
|
|
|
881b8e |
+ if (!info->shared
|
|
|
881b8e |
+ && h != NULL && &h->elf == htab->elf.hgot
|
|
|
881b8e |
+ && rel + 1 < relend
|
|
|
881b8e |
+ && rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_REL16_LO)
|
|
|
881b8e |
+ && rel[1].r_offset == rel->r_offset + 4
|
|
|
881b8e |
+ && rel[1].r_addend == rel->r_addend + 4
|
|
|
881b8e |
+ && relocation + 0x80008000 <= 0xffffffff)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ unsigned int insn1, insn2;
|
|
|
881b8e |
+ bfd_vma offset = rel->r_offset - d_offset;
|
|
|
881b8e |
+ insn1 = bfd_get_32 (output_bfd, contents + offset);
|
|
|
881b8e |
+ insn2 = bfd_get_32 (output_bfd, contents + offset + 4);
|
|
|
881b8e |
+ if ((insn1 & 0xffff0000) == 0x3c4c0000 /* addis 2,12 */
|
|
|
881b8e |
+ && (insn2 & 0xffff0000) == 0x38420000 /* addi 2,2 */)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ r_type = R_PPC64_ADDR16_HA;
|
|
|
881b8e |
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
|
|
|
881b8e |
+ rel->r_addend -= d_offset;
|
|
|
881b8e |
+ rel[1].r_info = ELF64_R_INFO (r_symndx, R_PPC64_ADDR16_LO);
|
|
|
881b8e |
+ rel[1].r_addend -= d_offset + 4;
|
|
|
881b8e |
+ bfd_put_32 (output_bfd, 0x3c400000, contents + offset);
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
/* Handle other relocations that tweak non-addend part of insn. */
|
|
|
881b8e |
@@ -12871,7 +13446,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|
|
881b8e |
insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
|
|
|
881b8e |
if (insn == NOP
|
|
|
881b8e |
|| insn == CROR_151515 || insn == CROR_313131)
|
|
|
881b8e |
- bfd_put_32 (input_bfd, STD_R2_40R1,
|
|
|
881b8e |
+ bfd_put_32 (input_bfd,
|
|
|
881b8e |
+ STD_R2_0R1 + STK_TOC (htab),
|
|
|
881b8e |
contents + rel->r_offset);
|
|
|
881b8e |
}
|
|
|
881b8e |
break;
|
|
|
881b8e |
@@ -13001,6 +13577,10 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|
|
881b8e |
+ input_section->output_offset
|
|
|
881b8e |
+ input_section->output_section->vma);
|
|
|
881b8e |
|
|
|
881b8e |
+ relocation += PPC64_LOCAL_ENTRY_OFFSET (fdh
|
|
|
881b8e |
+ ? fdh->elf.other
|
|
|
881b8e |
+ : sym->st_other);
|
|
|
881b8e |
+
|
|
|
881b8e |
if (stub_entry != NULL
|
|
|
881b8e |
&& (stub_entry->stub_type == ppc_stub_long_branch
|
|
|
881b8e |
|| stub_entry->stub_type == ppc_stub_plt_branch)
|
|
|
881b8e |
@@ -13154,7 +13734,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|
|
881b8e |
if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared,
|
|
|
881b8e |
&h->elf)
|
|
|
881b8e |
|| (info->shared
|
|
|
881b8e |
- && SYMBOL_CALLS_LOCAL (info, &h->elf)))
|
|
|
881b8e |
+ && SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
|
|
|
881b8e |
/* This is actually a static link, or it is a
|
|
|
881b8e |
-Bsymbolic link and the symbol is defined
|
|
|
881b8e |
locally, or the symbol was forced to be local
|
|
|
881b8e |
@@ -13329,13 +13909,14 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|
|
881b8e |
{
|
|
|
881b8e |
struct plt_entry *ent;
|
|
|
881b8e |
for (ent = h->elf.plt.plist; ent != NULL; ent = ent->next)
|
|
|
881b8e |
- if (ent->addend == orig_rel.r_addend
|
|
|
881b8e |
- && ent->plt.offset != (bfd_vma) -1)
|
|
|
881b8e |
+ if (ent->plt.offset != (bfd_vma) -1
|
|
|
881b8e |
+ && ent->addend == orig_rel.r_addend)
|
|
|
881b8e |
{
|
|
|
881b8e |
relocation = (htab->plt->output_section->vma
|
|
|
881b8e |
+ htab->plt->output_offset
|
|
|
881b8e |
+ ent->plt.offset);
|
|
|
881b8e |
unresolved_reloc = FALSE;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
}
|
|
|
881b8e |
}
|
|
|
881b8e |
break;
|
|
|
881b8e |
@@ -13395,6 +13976,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|
|
881b8e |
case R_PPC64_TPREL16_HA:
|
|
|
881b8e |
case R_PPC64_TPREL16_DS:
|
|
|
881b8e |
case R_PPC64_TPREL16_LO_DS:
|
|
|
881b8e |
+ case R_PPC64_TPREL16_HIGH:
|
|
|
881b8e |
+ case R_PPC64_TPREL16_HIGHA:
|
|
|
881b8e |
case R_PPC64_TPREL16_HIGHER:
|
|
|
881b8e |
case R_PPC64_TPREL16_HIGHERA:
|
|
|
881b8e |
case R_PPC64_TPREL16_HIGHEST:
|
|
|
881b8e |
@@ -13429,6 +14012,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|
|
881b8e |
case R_PPC64_DTPREL16_HA:
|
|
|
881b8e |
case R_PPC64_DTPREL16_DS:
|
|
|
881b8e |
case R_PPC64_DTPREL16_LO_DS:
|
|
|
881b8e |
+ case R_PPC64_DTPREL16_HIGH:
|
|
|
881b8e |
+ case R_PPC64_DTPREL16_HIGHA:
|
|
|
881b8e |
case R_PPC64_DTPREL16_HIGHER:
|
|
|
881b8e |
case R_PPC64_DTPREL16_HIGHERA:
|
|
|
881b8e |
case R_PPC64_DTPREL16_HIGHEST:
|
|
|
881b8e |
@@ -13461,6 +14046,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|
|
881b8e |
case R_PPC64_ADDR16_DS:
|
|
|
881b8e |
case R_PPC64_ADDR16_HA:
|
|
|
881b8e |
case R_PPC64_ADDR16_HI:
|
|
|
881b8e |
+ case R_PPC64_ADDR16_HIGH:
|
|
|
881b8e |
+ case R_PPC64_ADDR16_HIGHA:
|
|
|
881b8e |
case R_PPC64_ADDR16_HIGHER:
|
|
|
881b8e |
case R_PPC64_ADDR16_HIGHERA:
|
|
|
881b8e |
case R_PPC64_ADDR16_HIGHEST:
|
|
|
881b8e |
@@ -13532,7 +14119,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|
|
881b8e |
|
|
|
881b8e |
if (skip)
|
|
|
881b8e |
memset (&outrel, 0, sizeof outrel);
|
|
|
881b8e |
- else if (!SYMBOL_CALLS_LOCAL (info, &h->elf)
|
|
|
881b8e |
+ else if (!SYMBOL_REFERENCES_LOCAL (info, &h->elf)
|
|
|
881b8e |
&& !is_opd
|
|
|
881b8e |
&& r_type != R_PPC64_TOC)
|
|
|
881b8e |
{
|
|
|
881b8e |
@@ -13776,21 +14363,20 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|
|
881b8e |
default:
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
- case R_PPC64_ADDR16_HA:
|
|
|
881b8e |
case R_PPC64_REL16_HA:
|
|
|
881b8e |
+ case R_PPC64_ADDR16_HA:
|
|
|
881b8e |
+ case R_PPC64_ADDR16_HIGHA:
|
|
|
881b8e |
case R_PPC64_ADDR16_HIGHERA:
|
|
|
881b8e |
case R_PPC64_ADDR16_HIGHESTA:
|
|
|
881b8e |
case R_PPC64_TOC16_HA:
|
|
|
881b8e |
case R_PPC64_SECTOFF_HA:
|
|
|
881b8e |
case R_PPC64_TPREL16_HA:
|
|
|
881b8e |
- case R_PPC64_DTPREL16_HA:
|
|
|
881b8e |
- case R_PPC64_TPREL16_HIGHER:
|
|
|
881b8e |
+ case R_PPC64_TPREL16_HIGHA:
|
|
|
881b8e |
case R_PPC64_TPREL16_HIGHERA:
|
|
|
881b8e |
- case R_PPC64_TPREL16_HIGHEST:
|
|
|
881b8e |
case R_PPC64_TPREL16_HIGHESTA:
|
|
|
881b8e |
- case R_PPC64_DTPREL16_HIGHER:
|
|
|
881b8e |
+ case R_PPC64_DTPREL16_HA:
|
|
|
881b8e |
+ case R_PPC64_DTPREL16_HIGHA:
|
|
|
881b8e |
case R_PPC64_DTPREL16_HIGHERA:
|
|
|
881b8e |
- case R_PPC64_DTPREL16_HIGHEST:
|
|
|
881b8e |
case R_PPC64_DTPREL16_HIGHESTA:
|
|
|
881b8e |
/* It's just possible that this symbol is a weak symbol
|
|
|
881b8e |
that's not actually defined anywhere. In that case,
|
|
|
881b8e |
@@ -14017,7 +14603,10 @@ ppc64_elf_finish_dynamic_symbol (bfd *output_bfd,
|
|
|
881b8e |
rela.r_offset = (htab->iplt->output_section->vma
|
|
|
881b8e |
+ htab->iplt->output_offset
|
|
|
881b8e |
+ ent->plt.offset);
|
|
|
881b8e |
- rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
|
|
|
881b8e |
+ if (htab->opd_abi)
|
|
|
881b8e |
+ rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
|
|
|
881b8e |
+ else
|
|
|
881b8e |
+ rela.r_info = ELF64_R_INFO (0, R_PPC64_IRELATIVE);
|
|
|
881b8e |
rela.r_addend = (h->root.u.def.value
|
|
|
881b8e |
+ h->root.u.def.section->output_offset
|
|
|
881b8e |
+ h->root.u.def.section->output_section->vma
|
|
|
881b8e |
@@ -14034,10 +14623,34 @@ ppc64_elf_finish_dynamic_symbol (bfd *output_bfd,
|
|
|
881b8e |
rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_JMP_SLOT);
|
|
|
881b8e |
rela.r_addend = ent->addend;
|
|
|
881b8e |
loc = (htab->relplt->contents
|
|
|
881b8e |
- + ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE)
|
|
|
881b8e |
- / (PLT_ENTRY_SIZE / sizeof (Elf64_External_Rela))));
|
|
|
881b8e |
+ + ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE (htab))
|
|
|
881b8e |
+ / PLT_ENTRY_SIZE (htab) * sizeof (Elf64_External_Rela)));
|
|
|
881b8e |
}
|
|
|
881b8e |
bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (!htab->opd_abi)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ if (!h->def_regular)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ /* Mark the symbol as undefined, rather than as
|
|
|
881b8e |
+ defined in glink. Leave the value if there were
|
|
|
881b8e |
+ any relocations where pointer equality matters
|
|
|
881b8e |
+ (this is a clue for the dynamic linker, to make
|
|
|
881b8e |
+ function pointer comparisons work between an
|
|
|
881b8e |
+ application and shared library), otherwise set it
|
|
|
881b8e |
+ to zero. */
|
|
|
881b8e |
+ sym->st_shndx = SHN_UNDEF;
|
|
|
881b8e |
+ if (!h->pointer_equality_needed)
|
|
|
881b8e |
+ sym->st_value = 0;
|
|
|
881b8e |
+ else if (!h->ref_regular_nonweak)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ /* This breaks function pointer comparisons, but
|
|
|
881b8e |
+ that is better than breaking tests for a NULL
|
|
|
881b8e |
+ function pointer. */
|
|
|
881b8e |
+ sym->st_value = 0;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ }
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
if (h->needs_copy)
|
|
|
881b8e |
@@ -14130,7 +14743,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
|
|
|
881b8e |
of glink rather than the first entry point, which is
|
|
|
881b8e |
what ld.so needs, and now have a bigger stub to
|
|
|
881b8e |
support automatic multiple TOCs. */
|
|
|
881b8e |
- dyn.d_un.d_ptr += GLINK_CALL_STUB_SIZE - 32;
|
|
|
881b8e |
+ dyn.d_un.d_ptr += GLINK_CALL_STUB_SIZE - 8 * 4;
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
case DT_PPC64_OPD:
|
|
|
881b8e |
@@ -14140,6 +14753,11 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
|
|
|
881b8e |
dyn.d_un.d_ptr = s->vma;
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
+ case DT_PPC64_OPT:
|
|
|
881b8e |
+ if (htab->do_multi_toc && htab->multi_toc_needed)
|
|
|
881b8e |
+ dyn.d_un.d_val |= PPC64_OPT_MULTI_TOC;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
+
|
|
|
881b8e |
case DT_PPC64_OPDSZ:
|
|
|
881b8e |
s = bfd_get_section_by_name (output_bfd, ".opd");
|
|
|
881b8e |
if (s == NULL)
|
|
|
881b8e |
@@ -14203,7 +14821,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
|
|
|
881b8e |
{
|
|
|
881b8e |
/* Set .plt entry size. */
|
|
|
881b8e |
elf_section_data (htab->plt->output_section)->this_hdr.sh_entsize
|
|
|
881b8e |
- = PLT_ENTRY_SIZE;
|
|
|
881b8e |
+ = PLT_ENTRY_SIZE (htab);
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
/* brlt is SEC_LINKER_CREATED, so we need to write out relocs for
|
|
|
881b8e |
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
|
|
|
881b8e |
index bcd76a0..d3b7950 100644
|
|
|
881b8e |
--- a/bfd/libbfd.h
|
|
|
881b8e |
+++ b/bfd/libbfd.h
|
|
|
881b8e |
@@ -1396,6 +1396,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
|
|
881b8e |
"BFD_RELOC_PPC64_TOC16_LO_DS",
|
|
|
881b8e |
"BFD_RELOC_PPC64_PLTGOT16_DS",
|
|
|
881b8e |
"BFD_RELOC_PPC64_PLTGOT16_LO_DS",
|
|
|
881b8e |
+ "BFD_RELOC_PPC64_ADDR16_HIGH",
|
|
|
881b8e |
+ "BFD_RELOC_PPC64_ADDR16_HIGHA",
|
|
|
881b8e |
"BFD_RELOC_PPC_TLS",
|
|
|
881b8e |
"BFD_RELOC_PPC_TLSGD",
|
|
|
881b8e |
"BFD_RELOC_PPC_TLSLD",
|
|
|
881b8e |
@@ -1438,6 +1440,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
|
|
881b8e |
"BFD_RELOC_PPC64_DTPREL16_HIGHERA",
|
|
|
881b8e |
"BFD_RELOC_PPC64_DTPREL16_HIGHEST",
|
|
|
881b8e |
"BFD_RELOC_PPC64_DTPREL16_HIGHESTA",
|
|
|
881b8e |
+ "BFD_RELOC_PPC64_TPREL16_HIGH",
|
|
|
881b8e |
+ "BFD_RELOC_PPC64_TPREL16_HIGHA",
|
|
|
881b8e |
+ "BFD_RELOC_PPC64_DTPREL16_HIGH",
|
|
|
881b8e |
+ "BFD_RELOC_PPC64_DTPREL16_HIGHA",
|
|
|
881b8e |
"BFD_RELOC_I370_D12",
|
|
|
881b8e |
"BFD_RELOC_CTOR",
|
|
|
881b8e |
"BFD_RELOC_ARM_PCREL_BRANCH",
|
|
|
881b8e |
diff --git a/bfd/reloc.c b/bfd/reloc.c
|
|
|
881b8e |
index 626c818..b924974 100644
|
|
|
881b8e |
--- a/bfd/reloc.c
|
|
|
881b8e |
+++ b/bfd/reloc.c
|
|
|
881b8e |
@@ -2892,6 +2892,10 @@ ENUMX
|
|
|
881b8e |
BFD_RELOC_PPC64_PLTGOT16_DS
|
|
|
881b8e |
ENUMX
|
|
|
881b8e |
BFD_RELOC_PPC64_PLTGOT16_LO_DS
|
|
|
881b8e |
+ENUMX
|
|
|
881b8e |
+ BFD_RELOC_PPC64_ADDR16_HIGH
|
|
|
881b8e |
+ENUMX
|
|
|
881b8e |
+ BFD_RELOC_PPC64_ADDR16_HIGHA
|
|
|
881b8e |
ENUMDOC
|
|
|
881b8e |
Power(rs6000) and PowerPC relocations.
|
|
|
881b8e |
|
|
|
881b8e |
@@ -2979,6 +2983,14 @@ ENUMX
|
|
|
881b8e |
BFD_RELOC_PPC64_DTPREL16_HIGHEST
|
|
|
881b8e |
ENUMX
|
|
|
881b8e |
BFD_RELOC_PPC64_DTPREL16_HIGHESTA
|
|
|
881b8e |
+ENUMX
|
|
|
881b8e |
+ BFD_RELOC_PPC64_TPREL16_HIGH
|
|
|
881b8e |
+ENUMX
|
|
|
881b8e |
+ BFD_RELOC_PPC64_TPREL16_HIGHA
|
|
|
881b8e |
+ENUMX
|
|
|
881b8e |
+ BFD_RELOC_PPC64_DTPREL16_HIGH
|
|
|
881b8e |
+ENUMX
|
|
|
881b8e |
+ BFD_RELOC_PPC64_DTPREL16_HIGHA
|
|
|
881b8e |
ENUMDOC
|
|
|
881b8e |
PowerPC and PowerPC64 thread-local storage relocations.
|
|
|
881b8e |
|
|
|
881b8e |
diff --git a/binutils/readelf.c b/binutils/readelf.c
|
|
|
881b8e |
index 67aeaa8..2046ec5 100644
|
|
|
881b8e |
--- a/binutils/readelf.c
|
|
|
881b8e |
+++ b/binutils/readelf.c
|
|
|
881b8e |
@@ -1556,7 +1556,7 @@ get_ppc_dynamic_type (unsigned long type)
|
|
|
881b8e |
switch (type)
|
|
|
881b8e |
{
|
|
|
881b8e |
case DT_PPC_GOT: return "PPC_GOT";
|
|
|
881b8e |
- case DT_PPC_TLSOPT: return "PPC_TLSOPT";
|
|
|
881b8e |
+ case DT_PPC_OPT: return "PPC_OPT";
|
|
|
881b8e |
default:
|
|
|
881b8e |
return NULL;
|
|
|
881b8e |
}
|
|
|
881b8e |
@@ -1570,7 +1570,7 @@ get_ppc64_dynamic_type (unsigned long type)
|
|
|
881b8e |
case DT_PPC64_GLINK: return "PPC64_GLINK";
|
|
|
881b8e |
case DT_PPC64_OPD: return "PPC64_OPD";
|
|
|
881b8e |
case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
|
|
|
881b8e |
- case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
|
|
|
881b8e |
+ case DT_PPC64_OPT: return "PPC64_OPT";
|
|
|
881b8e |
default:
|
|
|
881b8e |
return NULL;
|
|
|
881b8e |
}
|
|
|
881b8e |
@@ -2442,6 +2442,16 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
|
|
|
881b8e |
strcat (buf, _(", relocatable-lib"));
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
+ case EM_PPC64:
|
|
|
881b8e |
+ if (e_flags & EF_PPC64_ABI)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ char abi[] = ", abiv0";
|
|
|
881b8e |
+
|
|
|
881b8e |
+ abi[6] += e_flags & EF_PPC64_ABI;
|
|
|
881b8e |
+ strcat (buf, abi);
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
+
|
|
|
881b8e |
case EM_V800:
|
|
|
881b8e |
if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
|
|
|
881b8e |
strcat (buf, ", RH850 ABI");
|
|
|
881b8e |
@@ -9122,6 +9132,19 @@ get_ia64_symbol_other (unsigned int other)
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
static const char *
|
|
|
881b8e |
+get_ppc64_symbol_other (unsigned int other)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ static char buf[32];
|
|
|
881b8e |
+ snprintf (buf, sizeof buf, _("<localentry>: %d"),
|
|
|
881b8e |
+ PPC64_LOCAL_ENTRY_OFFSET (other));
|
|
|
881b8e |
+ return buf;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ return NULL;
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
+static const char *
|
|
|
881b8e |
get_symbol_other (unsigned int other)
|
|
|
881b8e |
{
|
|
|
881b8e |
const char * result = NULL;
|
|
|
881b8e |
@@ -9138,6 +9161,9 @@ get_symbol_other (unsigned int other)
|
|
|
881b8e |
case EM_IA_64:
|
|
|
881b8e |
result = get_ia64_symbol_other (other);
|
|
|
881b8e |
break;
|
|
|
881b8e |
+ case EM_PPC64:
|
|
|
881b8e |
+ result = get_ppc64_symbol_other (other);
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
default:
|
|
|
881b8e |
break;
|
|
|
881b8e |
}
|
|
|
881b8e |
diff --git a/elfcpp/powerpc.h b/elfcpp/powerpc.h
|
|
|
881b8e |
index 2c803af..879055e 100644
|
|
|
881b8e |
--- a/elfcpp/powerpc.h
|
|
|
881b8e |
+++ b/elfcpp/powerpc.h
|
|
|
881b8e |
@@ -164,11 +164,17 @@ enum
|
|
|
881b8e |
R_PPC_EMB_SDA21 = 109,
|
|
|
881b8e |
R_PPC64_TOCSAVE = 109,
|
|
|
881b8e |
R_PPC_EMB_MRKREF = 110,
|
|
|
881b8e |
+ R_PPC64_ADDR16_HIGH = 110,
|
|
|
881b8e |
R_PPC_EMB_RELSEC16 = 111,
|
|
|
881b8e |
+ R_PPC64_ADDR16_HIGHA = 111,
|
|
|
881b8e |
R_PPC_EMB_RELST_LO = 112,
|
|
|
881b8e |
+ R_PPC64_TPREL16_HIGH = 112,
|
|
|
881b8e |
R_PPC_EMB_RELST_HI = 113,
|
|
|
881b8e |
+ R_PPC64_TPREL16_HIGHA = 113,
|
|
|
881b8e |
R_PPC_EMB_RELST_HA = 114,
|
|
|
881b8e |
+ R_PPC64_DTPREL16_HIGH = 114,
|
|
|
881b8e |
R_PPC_EMB_BIT_FLD = 115,
|
|
|
881b8e |
+ R_PPC64_DTPREL16_HIGHA = 115,
|
|
|
881b8e |
R_PPC_EMB_RELSDA = 116,
|
|
|
881b8e |
|
|
|
881b8e |
R_PPC_VLE_REL8 = 216,
|
|
|
881b8e |
@@ -208,6 +214,59 @@ enum
|
|
|
881b8e |
EF_PPC_RELOCATABLE_LIB = 0x00008000, // PowerPC -mrelocatable-lib flag. */
|
|
|
881b8e |
};
|
|
|
881b8e |
|
|
|
881b8e |
+// e_flags values defined for powerpc64
|
|
|
881b8e |
+enum
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ // ABI version
|
|
|
881b8e |
+ // 1 for original function descriptor using ABI,
|
|
|
881b8e |
+ // 2 for revised ABI without function descriptors,
|
|
|
881b8e |
+ // 0 for unspecified or not using any features affected by the differences.
|
|
|
881b8e |
+ EF_PPC64_ABI = 3
|
|
|
881b8e |
+};
|
|
|
881b8e |
+
|
|
|
881b8e |
+enum
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ // The ELFv2 ABI uses three bits in the symbol st_other field of a
|
|
|
881b8e |
+ // function definition to specify the number of instructions between a
|
|
|
881b8e |
+ // function's global entry point and local entry point.
|
|
|
881b8e |
+ // The global entry point is used when it is necessary to set up the
|
|
|
881b8e |
+ // toc pointer (r2) for the function. Callers must enter the global
|
|
|
881b8e |
+ // entry point with r12 set to the global entry point address. On
|
|
|
881b8e |
+ // return from the function, r2 may have a different value to that
|
|
|
881b8e |
+ // which it had on entry.
|
|
|
881b8e |
+ // The local entry point is used when r2 is known to already be valid
|
|
|
881b8e |
+ // for the function. There is no requirement on r12 when using the
|
|
|
881b8e |
+ // local entry point, and on return r2 will contain the same value as
|
|
|
881b8e |
+ // at entry.
|
|
|
881b8e |
+ // A value of zero in these bits means that the function has a single
|
|
|
881b8e |
+ // entry point with no requirement on r12 or r2, and that on return r2
|
|
|
881b8e |
+ // will contain the same value as at entry.
|
|
|
881b8e |
+ // Values of one and seven are reserved.
|
|
|
881b8e |
+
|
|
|
881b8e |
+ STO_PPC64_LOCAL_BIT = 5,
|
|
|
881b8e |
+ STO_PPC64_LOCAL_MASK = 0xE0
|
|
|
881b8e |
+};
|
|
|
881b8e |
+
|
|
|
881b8e |
+// 3 bit other field to bytes.
|
|
|
881b8e |
+static inline unsigned int
|
|
|
881b8e |
+ppc64_decode_local_entry(unsigned int other)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ return ((1 << other) >> 2) << 2;
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
+// bytes to field value.
|
|
|
881b8e |
+static inline unsigned int
|
|
|
881b8e |
+ppc64_encode_local_entry(unsigned int val)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ return (val >= 4 * 4
|
|
|
881b8e |
+ ? (val >= 8 * 4
|
|
|
881b8e |
+ ? (val >= 16 * 4 ? 6 : 5)
|
|
|
881b8e |
+ : 4)
|
|
|
881b8e |
+ : (val >= 2 * 4
|
|
|
881b8e |
+ ? 3
|
|
|
881b8e |
+ : (val >= 1 * 4 ? 2 : 0)));
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
} // End namespace elfcpp.
|
|
|
881b8e |
|
|
|
881b8e |
#endif // !defined(ELFCPP_POWERPC_H)
|
|
|
881b8e |
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
|
|
|
881b8e |
index e55d8a9..99e893d 100644
|
|
|
881b8e |
--- a/gas/config/tc-ppc.c
|
|
|
881b8e |
+++ b/gas/config/tc-ppc.c
|
|
|
881b8e |
@@ -29,6 +29,7 @@
|
|
|
881b8e |
|
|
|
881b8e |
#ifdef OBJ_ELF
|
|
|
881b8e |
#include "elf/ppc.h"
|
|
|
881b8e |
+#include "elf/ppc64.h"
|
|
|
881b8e |
#include "dwarf2dbg.h"
|
|
|
881b8e |
#endif
|
|
|
881b8e |
|
|
|
881b8e |
@@ -112,7 +113,11 @@ static int set_target_endian = 0;
|
|
|
881b8e |
compensating for #lo being treated as a signed number. */
|
|
|
881b8e |
#define PPC_HIGHESTA(v) PPC_HIGHEST ((v) + 0x8000)
|
|
|
881b8e |
|
|
|
881b8e |
-#define SEX16(val) ((((val) & 0xffff) ^ 0x8000) - 0x8000)
|
|
|
881b8e |
+#define SEX16(val) (((val) ^ 0x8000) - 0x8000)
|
|
|
881b8e |
+
|
|
|
881b8e |
+/* For the time being on ppc64, don't report overflow on @h and @ha
|
|
|
881b8e |
+ applied to constants. */
|
|
|
881b8e |
+#define REPORT_OVERFLOW_HI 0
|
|
|
881b8e |
|
|
|
881b8e |
static bfd_boolean reg_names_p = TARGET_REG_NAMES_P;
|
|
|
881b8e |
|
|
|
881b8e |
@@ -155,6 +160,8 @@ static void ppc_vbyte (int);
|
|
|
881b8e |
static void ppc_elf_cons (int);
|
|
|
881b8e |
static void ppc_elf_rdata (int);
|
|
|
881b8e |
static void ppc_elf_lcomm (int);
|
|
|
881b8e |
+static void ppc_elf_localentry (int);
|
|
|
881b8e |
+static void ppc_elf_abiversion (int);
|
|
|
881b8e |
#endif
|
|
|
881b8e |
|
|
|
881b8e |
#ifdef TE_PE
|
|
|
881b8e |
@@ -225,6 +232,9 @@ unsigned long nop_limit = 4;
|
|
|
881b8e |
ppc_cpu_t ppc_cpu = 0;
|
|
|
881b8e |
ppc_cpu_t sticky = 0;
|
|
|
881b8e |
|
|
|
881b8e |
+/* Value for ELF e_flags EF_PPC64_ABI. */
|
|
|
881b8e |
+unsigned int ppc_abiversion = 0;
|
|
|
881b8e |
+
|
|
|
881b8e |
/* Flags set on encountering toc relocs. */
|
|
|
881b8e |
enum {
|
|
|
881b8e |
has_large_toc_reloc = 1,
|
|
|
881b8e |
@@ -283,6 +293,8 @@ const pseudo_typeS md_pseudo_table[] =
|
|
|
881b8e |
{ "rdata", ppc_elf_rdata, 0 },
|
|
|
881b8e |
{ "rodata", ppc_elf_rdata, 0 },
|
|
|
881b8e |
{ "lcomm", ppc_elf_lcomm, 0 },
|
|
|
881b8e |
+ { "localentry", ppc_elf_localentry, 0 },
|
|
|
881b8e |
+ { "abiversion", ppc_elf_abiversion, 0 },
|
|
|
881b8e |
#endif
|
|
|
881b8e |
|
|
|
881b8e |
#ifdef TE_PE
|
|
|
881b8e |
@@ -1949,6 +1961,8 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
|
|
|
881b8e |
MAP32 ("bitfld", BFD_RELOC_PPC_EMB_BIT_FLD),
|
|
|
881b8e |
MAP32 ("relsda", BFD_RELOC_PPC_EMB_RELSDA),
|
|
|
881b8e |
MAP32 ("xgot", BFD_RELOC_PPC_TOC16),
|
|
|
881b8e |
+ MAP64 ("high", BFD_RELOC_PPC64_ADDR16_HIGH),
|
|
|
881b8e |
+ MAP64 ("higha", BFD_RELOC_PPC64_ADDR16_HIGHA),
|
|
|
881b8e |
MAP64 ("higher", BFD_RELOC_PPC64_HIGHER),
|
|
|
881b8e |
MAP64 ("highera", BFD_RELOC_PPC64_HIGHER_S),
|
|
|
881b8e |
MAP64 ("highest", BFD_RELOC_PPC64_HIGHEST),
|
|
|
881b8e |
@@ -1958,10 +1972,14 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
|
|
|
881b8e |
MAP64 ("toc@l", BFD_RELOC_PPC64_TOC16_LO),
|
|
|
881b8e |
MAP64 ("toc@h", BFD_RELOC_PPC64_TOC16_HI),
|
|
|
881b8e |
MAP64 ("toc@ha", BFD_RELOC_PPC64_TOC16_HA),
|
|
|
881b8e |
+ MAP64 ("dtprel@high", BFD_RELOC_PPC64_DTPREL16_HIGH),
|
|
|
881b8e |
+ MAP64 ("dtprel@higha", BFD_RELOC_PPC64_DTPREL16_HIGHA),
|
|
|
881b8e |
MAP64 ("dtprel@higher", BFD_RELOC_PPC64_DTPREL16_HIGHER),
|
|
|
881b8e |
MAP64 ("dtprel@highera", BFD_RELOC_PPC64_DTPREL16_HIGHERA),
|
|
|
881b8e |
MAP64 ("dtprel@highest", BFD_RELOC_PPC64_DTPREL16_HIGHEST),
|
|
|
881b8e |
MAP64 ("dtprel@highesta", BFD_RELOC_PPC64_DTPREL16_HIGHESTA),
|
|
|
881b8e |
+ MAP64 ("tprel@high", BFD_RELOC_PPC64_TPREL16_HIGH),
|
|
|
881b8e |
+ MAP64 ("tprel@higha", BFD_RELOC_PPC64_TPREL16_HIGHA),
|
|
|
881b8e |
MAP64 ("tprel@higher", BFD_RELOC_PPC64_TPREL16_HIGHER),
|
|
|
881b8e |
MAP64 ("tprel@highera", BFD_RELOC_PPC64_TPREL16_HIGHERA),
|
|
|
881b8e |
MAP64 ("tprel@highest", BFD_RELOC_PPC64_TPREL16_HIGHEST),
|
|
|
881b8e |
@@ -2237,6 +2255,101 @@ ppc_elf_lcomm (int xxx ATTRIBUTE_UNUSED)
|
|
|
881b8e |
demand_empty_rest_of_line ();
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
+/* Pseudo op to set symbol local entry point. */
|
|
|
881b8e |
+static void
|
|
|
881b8e |
+ppc_elf_localentry (int ignore ATTRIBUTE_UNUSED)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ char *name = input_line_pointer;
|
|
|
881b8e |
+ char c = get_symbol_end ();
|
|
|
881b8e |
+ char *p;
|
|
|
881b8e |
+ expressionS exp;
|
|
|
881b8e |
+ symbolS *sym;
|
|
|
881b8e |
+ asymbol *bfdsym;
|
|
|
881b8e |
+ elf_symbol_type *elfsym;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ p = input_line_pointer;
|
|
|
881b8e |
+ *p = c;
|
|
|
881b8e |
+ SKIP_WHITESPACE ();
|
|
|
881b8e |
+ if (*input_line_pointer != ',')
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ *p = 0;
|
|
|
881b8e |
+ as_bad (_("expected comma after name `%s' in .localentry directive"),
|
|
|
881b8e |
+ name);
|
|
|
881b8e |
+ *p = c;
|
|
|
881b8e |
+ ignore_rest_of_line ();
|
|
|
881b8e |
+ return;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ input_line_pointer++;
|
|
|
881b8e |
+ expression (&exp);
|
|
|
881b8e |
+ if (exp.X_op == O_absent)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ as_bad (_("missing expression in .localentry directive"));
|
|
|
881b8e |
+ exp.X_op = O_constant;
|
|
|
881b8e |
+ exp.X_add_number = 0;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ *p = 0;
|
|
|
881b8e |
+ sym = symbol_find_or_make (name);
|
|
|
881b8e |
+ *p = c;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (resolve_expression (&exp)
|
|
|
881b8e |
+ && exp.X_op == O_constant)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ unsigned char encoded = PPC64_SET_LOCAL_ENTRY_OFFSET (exp.X_add_number);
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (exp.X_add_number != PPC64_LOCAL_ENTRY_OFFSET (encoded))
|
|
|
881b8e |
+ as_bad (_(".localentry expression for `%s' "
|
|
|
881b8e |
+ "is not a valid power of 2"), S_GET_NAME (sym));
|
|
|
881b8e |
+ else
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ bfdsym = symbol_get_bfdsym (sym);
|
|
|
881b8e |
+ elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
|
|
|
881b8e |
+ gas_assert (elfsym);
|
|
|
881b8e |
+ elfsym->internal_elf_sym.st_other &= ~STO_PPC64_LOCAL_MASK;
|
|
|
881b8e |
+ elfsym->internal_elf_sym.st_other |= encoded;
|
|
|
881b8e |
+ if (ppc_abiversion == 0)
|
|
|
881b8e |
+ ppc_abiversion = 2;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ else
|
|
|
881b8e |
+ as_bad (_(".localentry expression for `%s' "
|
|
|
881b8e |
+ "does not evaluate to a constant"), S_GET_NAME (sym));
|
|
|
881b8e |
+
|
|
|
881b8e |
+ demand_empty_rest_of_line ();
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
+/* Pseudo op to set ABI version. */
|
|
|
881b8e |
+static void
|
|
|
881b8e |
+ppc_elf_abiversion (int ignore ATTRIBUTE_UNUSED)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ expressionS exp;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ expression (&exp);
|
|
|
881b8e |
+ if (exp.X_op == O_absent)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ as_bad (_("missing expression in .abiversion directive"));
|
|
|
881b8e |
+ exp.X_op = O_constant;
|
|
|
881b8e |
+ exp.X_add_number = 0;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (resolve_expression (&exp)
|
|
|
881b8e |
+ && exp.X_op == O_constant)
|
|
|
881b8e |
+ ppc_abiversion = exp.X_add_number;
|
|
|
881b8e |
+ else
|
|
|
881b8e |
+ as_bad (_(".abiversion expression does not evaluate to a constant"));
|
|
|
881b8e |
+ demand_empty_rest_of_line ();
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
+/* Set ABI version in output file. */
|
|
|
881b8e |
+void
|
|
|
881b8e |
+ppc_elf_end (void)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ if (ppc_obj64 && ppc_abiversion != 0)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ elf_elfheader (stdoutput)->e_flags &= ~EF_PPC64_ABI;
|
|
|
881b8e |
+ elf_elfheader (stdoutput)->e_flags |= ppc_abiversion & EF_PPC64_ABI;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
/* Validate any relocations emitted for -mrelocatable, possibly adding
|
|
|
881b8e |
fixups for word relocations in writable segments, so we can adjust
|
|
|
881b8e |
them at runtime. */
|
|
|
881b8e |
@@ -2838,55 +2951,76 @@ md_assemble (char *str)
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
case BFD_RELOC_LO16:
|
|
|
881b8e |
- /* X_unsigned is the default, so if the user has done
|
|
|
881b8e |
- something which cleared it, we always produce a
|
|
|
881b8e |
- signed value. */
|
|
|
881b8e |
- if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
|
|
|
881b8e |
- ex.X_add_number &= 0xffff;
|
|
|
881b8e |
- else
|
|
|
881b8e |
+ ex.X_add_number &= 0xffff;
|
|
|
881b8e |
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
|
|
|
881b8e |
ex.X_add_number = SEX16 (ex.X_add_number);
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
case BFD_RELOC_HI16:
|
|
|
881b8e |
- if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
|
|
|
881b8e |
- ex.X_add_number = PPC_HI (ex.X_add_number);
|
|
|
881b8e |
- else
|
|
|
881b8e |
- ex.X_add_number = SEX16 (PPC_HI (ex.X_add_number));
|
|
|
881b8e |
+ if (REPORT_OVERFLOW_HI && ppc_obj64)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ /* PowerPC64 @h is tested for overflow. */
|
|
|
881b8e |
+ ex.X_add_number = (addressT) ex.X_add_number >> 16;
|
|
|
881b8e |
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ addressT sign = (((addressT) -1 >> 16) + 1) >> 1;
|
|
|
881b8e |
+ ex.X_add_number
|
|
|
881b8e |
+ = ((addressT) ex.X_add_number ^ sign) - sign;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ /* Fall thru */
|
|
|
881b8e |
+
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_ADDR16_HIGH:
|
|
|
881b8e |
+ ex.X_add_number = PPC_HI (ex.X_add_number);
|
|
|
881b8e |
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
|
|
|
881b8e |
+ ex.X_add_number = SEX16 (ex.X_add_number);
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
case BFD_RELOC_HI16_S:
|
|
|
881b8e |
- if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
|
|
|
881b8e |
- ex.X_add_number = PPC_HA (ex.X_add_number);
|
|
|
881b8e |
- else
|
|
|
881b8e |
- ex.X_add_number = SEX16 (PPC_HA (ex.X_add_number));
|
|
|
881b8e |
+ if (REPORT_OVERFLOW_HI && ppc_obj64)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ /* PowerPC64 @ha is tested for overflow. */
|
|
|
881b8e |
+ ex.X_add_number
|
|
|
881b8e |
+ = ((addressT) ex.X_add_number + 0x8000) >> 16;
|
|
|
881b8e |
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ addressT sign = (((addressT) -1 >> 16) + 1) >> 1;
|
|
|
881b8e |
+ ex.X_add_number
|
|
|
881b8e |
+ = ((addressT) ex.X_add_number ^ sign) - sign;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ /* Fall thru */
|
|
|
881b8e |
+
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_ADDR16_HIGHA:
|
|
|
881b8e |
+ ex.X_add_number = PPC_HA (ex.X_add_number);
|
|
|
881b8e |
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
|
|
|
881b8e |
+ ex.X_add_number = SEX16 (ex.X_add_number);
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
case BFD_RELOC_PPC64_HIGHER:
|
|
|
881b8e |
- if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
|
|
|
881b8e |
- ex.X_add_number = PPC_HIGHER (ex.X_add_number);
|
|
|
881b8e |
- else
|
|
|
881b8e |
- ex.X_add_number = SEX16 (PPC_HIGHER (ex.X_add_number));
|
|
|
881b8e |
+ ex.X_add_number = PPC_HIGHER (ex.X_add_number);
|
|
|
881b8e |
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
|
|
|
881b8e |
+ ex.X_add_number = SEX16 (ex.X_add_number);
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
case BFD_RELOC_PPC64_HIGHER_S:
|
|
|
881b8e |
- if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
|
|
|
881b8e |
- ex.X_add_number = PPC_HIGHERA (ex.X_add_number);
|
|
|
881b8e |
- else
|
|
|
881b8e |
- ex.X_add_number = SEX16 (PPC_HIGHERA (ex.X_add_number));
|
|
|
881b8e |
+ ex.X_add_number = PPC_HIGHERA (ex.X_add_number);
|
|
|
881b8e |
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
|
|
|
881b8e |
+ ex.X_add_number = SEX16 (ex.X_add_number);
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
case BFD_RELOC_PPC64_HIGHEST:
|
|
|
881b8e |
- if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
|
|
|
881b8e |
- ex.X_add_number = PPC_HIGHEST (ex.X_add_number);
|
|
|
881b8e |
- else
|
|
|
881b8e |
- ex.X_add_number = SEX16 (PPC_HIGHEST (ex.X_add_number));
|
|
|
881b8e |
+ ex.X_add_number = PPC_HIGHEST (ex.X_add_number);
|
|
|
881b8e |
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
|
|
|
881b8e |
+ ex.X_add_number = SEX16 (ex.X_add_number);
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
case BFD_RELOC_PPC64_HIGHEST_S:
|
|
|
881b8e |
- if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
|
|
|
881b8e |
- ex.X_add_number = PPC_HIGHESTA (ex.X_add_number);
|
|
|
881b8e |
- else
|
|
|
881b8e |
- ex.X_add_number = SEX16 (PPC_HIGHESTA (ex.X_add_number));
|
|
|
881b8e |
+ ex.X_add_number = PPC_HIGHESTA (ex.X_add_number);
|
|
|
881b8e |
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
|
|
|
881b8e |
+ ex.X_add_number = SEX16 (ex.X_add_number);
|
|
|
881b8e |
break;
|
|
|
881b8e |
}
|
|
|
881b8e |
#endif /* OBJ_ELF */
|
|
|
881b8e |
@@ -6172,6 +6306,22 @@ ppc_force_relocation (fixS *fix)
|
|
|
881b8e |
case BFD_RELOC_24_PLT_PCREL:
|
|
|
881b8e |
case BFD_RELOC_PPC64_TOC:
|
|
|
881b8e |
return 1;
|
|
|
881b8e |
+ case BFD_RELOC_PPC_B26:
|
|
|
881b8e |
+ case BFD_RELOC_PPC_BA26:
|
|
|
881b8e |
+ case BFD_RELOC_PPC_B16:
|
|
|
881b8e |
+ case BFD_RELOC_PPC_BA16:
|
|
|
881b8e |
+ /* All branch fixups targeting a localentry symbol must
|
|
|
881b8e |
+ force a relocation. */
|
|
|
881b8e |
+ if (fix->fx_addsy)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ asymbol *bfdsym = symbol_get_bfdsym (fix->fx_addsy);
|
|
|
881b8e |
+ elf_symbol_type *elfsym
|
|
|
881b8e |
+ = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
|
|
|
881b8e |
+ gas_assert (elfsym);
|
|
|
881b8e |
+ if ((STO_PPC64_LOCAL_MASK & elfsym->internal_elf_sym.st_other) != 0)
|
|
|
881b8e |
+ return 1;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
default:
|
|
|
881b8e |
break;
|
|
|
881b8e |
}
|
|
|
881b8e |
@@ -6186,6 +6336,32 @@ ppc_force_relocation (fixS *fix)
|
|
|
881b8e |
int
|
|
|
881b8e |
ppc_fix_adjustable (fixS *fix)
|
|
|
881b8e |
{
|
|
|
881b8e |
+ switch (fix->fx_r_type)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ /* All branch fixups targeting a localentry symbol must
|
|
|
881b8e |
+ continue using the symbol. */
|
|
|
881b8e |
+ case BFD_RELOC_PPC_B26:
|
|
|
881b8e |
+ case BFD_RELOC_PPC_BA26:
|
|
|
881b8e |
+ case BFD_RELOC_PPC_B16:
|
|
|
881b8e |
+ case BFD_RELOC_PPC_BA16:
|
|
|
881b8e |
+ case BFD_RELOC_PPC_B16_BRTAKEN:
|
|
|
881b8e |
+ case BFD_RELOC_PPC_B16_BRNTAKEN:
|
|
|
881b8e |
+ case BFD_RELOC_PPC_BA16_BRTAKEN:
|
|
|
881b8e |
+ case BFD_RELOC_PPC_BA16_BRNTAKEN:
|
|
|
881b8e |
+ if (fix->fx_addsy)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ asymbol *bfdsym = symbol_get_bfdsym (fix->fx_addsy);
|
|
|
881b8e |
+ elf_symbol_type *elfsym
|
|
|
881b8e |
+ = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
|
|
|
881b8e |
+ gas_assert (elfsym);
|
|
|
881b8e |
+ if ((STO_PPC64_LOCAL_MASK & elfsym->internal_elf_sym.st_other) != 0)
|
|
|
881b8e |
+ return 0;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
+ default:
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+
|
|
|
881b8e |
return (fix->fx_r_type != BFD_RELOC_16_GOTOFF
|
|
|
881b8e |
&& fix->fx_r_type != BFD_RELOC_LO16_GOTOFF
|
|
|
881b8e |
&& fix->fx_r_type != BFD_RELOC_HI16_GOTOFF
|
|
|
881b8e |
@@ -6465,10 +6641,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|
|
|
881b8e |
case BFD_RELOC_PPC_GOT_DTPREL16_HA:
|
|
|
881b8e |
case BFD_RELOC_PPC64_TPREL16_DS:
|
|
|
881b8e |
case BFD_RELOC_PPC64_TPREL16_LO_DS:
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_TPREL16_HIGH:
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_TPREL16_HIGHA:
|
|
|
881b8e |
case BFD_RELOC_PPC64_TPREL16_HIGHER:
|
|
|
881b8e |
case BFD_RELOC_PPC64_TPREL16_HIGHERA:
|
|
|
881b8e |
case BFD_RELOC_PPC64_TPREL16_HIGHEST:
|
|
|
881b8e |
case BFD_RELOC_PPC64_TPREL16_HIGHESTA:
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_DTPREL16_HIGH:
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_DTPREL16_HIGHA:
|
|
|
881b8e |
case BFD_RELOC_PPC64_DTPREL16_DS:
|
|
|
881b8e |
case BFD_RELOC_PPC64_DTPREL16_LO_DS:
|
|
|
881b8e |
case BFD_RELOC_PPC64_DTPREL16_HIGHER:
|
|
|
881b8e |
@@ -6836,10 +7016,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|
|
|
881b8e |
case BFD_RELOC_PPC64_TOC16_LO:
|
|
|
881b8e |
case BFD_RELOC_PPC64_TOC16_HI:
|
|
|
881b8e |
case BFD_RELOC_PPC64_TOC16_HA:
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_DTPREL16_HIGH:
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_DTPREL16_HIGHA:
|
|
|
881b8e |
case BFD_RELOC_PPC64_DTPREL16_HIGHER:
|
|
|
881b8e |
case BFD_RELOC_PPC64_DTPREL16_HIGHERA:
|
|
|
881b8e |
case BFD_RELOC_PPC64_DTPREL16_HIGHEST:
|
|
|
881b8e |
case BFD_RELOC_PPC64_DTPREL16_HIGHESTA:
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_TPREL16_HIGH:
|
|
|
881b8e |
+ case BFD_RELOC_PPC64_TPREL16_HIGHA:
|
|
|
881b8e |
case BFD_RELOC_PPC64_TPREL16_HIGHER:
|
|
|
881b8e |
case BFD_RELOC_PPC64_TPREL16_HIGHERA:
|
|
|
881b8e |
case BFD_RELOC_PPC64_TPREL16_HIGHEST:
|
|
|
881b8e |
diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h
|
|
|
881b8e |
index 3dd3f81..6095416 100644
|
|
|
881b8e |
--- a/gas/config/tc-ppc.h
|
|
|
881b8e |
+++ b/gas/config/tc-ppc.h
|
|
|
881b8e |
@@ -238,6 +238,9 @@ extern void ppc_frob_file_before_adjust (void);
|
|
|
881b8e |
#define tc_adjust_symtab() ppc_elf_adjust_symtab ()
|
|
|
881b8e |
extern void ppc_elf_adjust_symtab (void);
|
|
|
881b8e |
|
|
|
881b8e |
+extern void ppc_elf_end (void);
|
|
|
881b8e |
+#define md_end ppc_elf_end
|
|
|
881b8e |
+
|
|
|
881b8e |
#endif /* OBJ_ELF */
|
|
|
881b8e |
|
|
|
881b8e |
#if defined (OBJ_ELF) || defined (OBJ_XCOFF)
|
|
|
881b8e |
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
|
|
|
881b8e |
index e192885..38a36ac 100644
|
|
|
881b8e |
--- a/gold/powerpc.cc
|
|
|
881b8e |
+++ b/gold/powerpc.cc
|
|
|
881b8e |
@@ -72,12 +72,19 @@ public:
|
|
|
881b8e |
const typename elfcpp::Ehdr<size, big_endian>& ehdr)
|
|
|
881b8e |
: Sized_relobj_file<size, big_endian>(name, input_file, offset, ehdr),
|
|
|
881b8e |
special_(0), has_small_toc_reloc_(false), opd_valid_(false),
|
|
|
881b8e |
- opd_ent_(), access_from_map_(), has14_(), stub_table_()
|
|
|
881b8e |
- { }
|
|
|
881b8e |
+ opd_ent_(), access_from_map_(), has14_(), stub_table_(),
|
|
|
881b8e |
+ e_flags_(ehdr.get_e_flags()), st_other_()
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ this->set_abiversion(0);
|
|
|
881b8e |
+ }
|
|
|
881b8e |
|
|
|
881b8e |
~Powerpc_relobj()
|
|
|
881b8e |
{ }
|
|
|
881b8e |
|
|
|
881b8e |
+ // Read the symbols then set up st_other vector.
|
|
|
881b8e |
+ void
|
|
|
881b8e |
+ do_read_symbols(Read_symbols_data*);
|
|
|
881b8e |
+
|
|
|
881b8e |
// The .got2 section shndx.
|
|
|
881b8e |
unsigned int
|
|
|
881b8e |
got2_shndx() const
|
|
|
881b8e |
@@ -263,6 +270,22 @@ public:
|
|
|
881b8e |
return NULL;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
+ int
|
|
|
881b8e |
+ abiversion() const
|
|
|
881b8e |
+ { return this->e_flags_ & elfcpp::EF_PPC64_ABI; }
|
|
|
881b8e |
+
|
|
|
881b8e |
+ // Set ABI version for input and output
|
|
|
881b8e |
+ void
|
|
|
881b8e |
+ set_abiversion(int ver);
|
|
|
881b8e |
+
|
|
|
881b8e |
+ unsigned int
|
|
|
881b8e |
+ ppc64_local_entry_offset(const Symbol* sym) const
|
|
|
881b8e |
+ { return elfcpp::ppc64_decode_local_entry(sym->nonvis() >> 3); }
|
|
|
881b8e |
+
|
|
|
881b8e |
+ unsigned int
|
|
|
881b8e |
+ ppc64_local_entry_offset(unsigned int symndx) const
|
|
|
881b8e |
+ { return elfcpp::ppc64_decode_local_entry(this->st_other_[symndx] >> 5); }
|
|
|
881b8e |
+
|
|
|
881b8e |
private:
|
|
|
881b8e |
struct Opd_ent
|
|
|
881b8e |
{
|
|
|
881b8e |
@@ -316,6 +339,12 @@ private:
|
|
|
881b8e |
|
|
|
881b8e |
// The stub table to use for a given input section.
|
|
|
881b8e |
std::vector<Stub_table<size, big_endian>*> stub_table_;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ // Header e_flags
|
|
|
881b8e |
+ elfcpp::Elf_Word e_flags_;
|
|
|
881b8e |
+
|
|
|
881b8e |
+ // ELF st_other field for local symbols.
|
|
|
881b8e |
+ std::vector<unsigned char> st_other_;
|
|
|
881b8e |
};
|
|
|
881b8e |
|
|
|
881b8e |
template<int size, bool big_endian>
|
|
|
881b8e |
@@ -1305,6 +1334,14 @@ public:
|
|
|
881b8e |
STATUS_OVERFLOW
|
|
|
881b8e |
};
|
|
|
881b8e |
|
|
|
881b8e |
+ int
|
|
|
881b8e |
+ abiversion() const
|
|
|
881b8e |
+ { return this->e_flags_ & elfcpp::EF_PPC64_ABI; }
|
|
|
881b8e |
+
|
|
|
881b8e |
+ // Set ABI version for input and output.
|
|
|
881b8e |
+ void
|
|
|
881b8e |
+ set_abiversion(int ver);
|
|
|
881b8e |
+
|
|
|
881b8e |
private:
|
|
|
881b8e |
typedef Powerpc_relocate_functions<size, big_endian> This;
|
|
|
881b8e |
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
|
|
|
881b8e |
@@ -1930,6 +1967,24 @@ class Stub_control
|
|
|
881b8e |
output_section()
|
|
|
881b8e |
{ return output_section_; }
|
|
|
881b8e |
|
|
|
881b8e |
+ int
|
|
|
881b8e |
+ abiversion () const
|
|
|
881b8e |
+ { return this->processor_specific_flags() & elfcpp::EF_PPC64_ABI; }
|
|
|
881b8e |
+
|
|
|
881b8e |
+ void
|
|
|
881b8e |
+ set_abiversion (int ver)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ elfcpp::Elf_Word flags = this->processor_specific_flags();
|
|
|
881b8e |
+ flags &= ~elfcpp::EF_PPC64_ABI;
|
|
|
881b8e |
+ flags |= ver & elfcpp::EF_PPC64_ABI;
|
|
|
881b8e |
+ this->set_processor_specific_flags(flags);
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+
|
|
|
881b8e |
+ // Offset to to save stack slot
|
|
|
881b8e |
+ int
|
|
|
881b8e |
+ stk_toc () const
|
|
|
881b8e |
+ { return this->abiversion() < 2 ? 40 : 24; }
|
|
|
881b8e |
+
|
|
|
881b8e |
private:
|
|
|
881b8e |
typedef enum
|
|
|
881b8e |
{
|
|
|
881b8e |
@@ -3605,6 +3660,26 @@ Stub_table<size, big_endian>::do_write(Output_file* of)
|
|
|
881b8e |
}
|
|
|
881b8e |
}
|
|
|
881b8e |
}
|
|
|
881b8e |
+ else
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ // Define .TOC. as for 32-bit _GLOBAL_OFFSET_TABLE_
|
|
|
881b8e |
+ Symbol *gotsym = symtab->lookup(".TOC.", NULL);
|
|
|
881b8e |
+ if (gotsym != NULL && gotsym->is_undefined())
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ Target_powerpc<size, big_endian>* target =
|
|
|
881b8e |
+ static_cast<Target_powerpc<size, big_endian>*>(
|
|
|
881b8e |
+ parameters->sized_target<size, big_endian>());
|
|
|
881b8e |
+ Output_data_got_powerpc<size, big_endian>* got
|
|
|
881b8e |
+ = target->got_section(symtab, layout);
|
|
|
881b8e |
+ symtab->define_in_output_data(".TOC.", NULL,
|
|
|
881b8e |
+ Symbol_table::PREDEFINED,
|
|
|
881b8e |
+ got, 0x8000, 0,
|
|
|
881b8e |
+ elfcpp::STT_OBJECT,
|
|
|
881b8e |
+ elfcpp::STB_LOCAL,
|
|
|
881b8e |
+ elfcpp::STV_HIDDEN, 0,
|
|
|
881b8e |
+ false, false);
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ }
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
// Write out .glink.
|
|
|
881b8e |
@@ -3632,16 +3707,34 @@ Output_data_glink<size, big_endian>::do_write(Output_file* of)
|
|
|
881b8e |
|
|
|
881b8e |
elfcpp::Swap<64, big_endian>::writeval(p, pltoff), p += 8;
|
|
|
881b8e |
|
|
|
881b8e |
- write_insn<big_endian>(p, mflr_12), p += 4;
|
|
|
881b8e |
- write_insn<big_endian>(p, bcl_20_31), p += 4;
|
|
|
881b8e |
- write_insn<big_endian>(p, mflr_11), p += 4;
|
|
|
881b8e |
- write_insn<big_endian>(p, ld_2_11 + l(-16)), p += 4;
|
|
|
881b8e |
- write_insn<big_endian>(p, mtlr_12), p += 4;
|
|
|
881b8e |
- write_insn<big_endian>(p, add_12_2_11), p += 4;
|
|
|
881b8e |
- write_insn<big_endian>(p, ld_11_12 + 0), p += 4;
|
|
|
881b8e |
- write_insn<big_endian>(p, ld_2_12 + 8), p += 4;
|
|
|
881b8e |
- write_insn<big_endian>(p, mtctr_11), p += 4;
|
|
|
881b8e |
- write_insn<big_endian>(p, ld_11_12 + 16), p += 4;
|
|
|
881b8e |
+ if (this->targ_->abiversion() < 2)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ write_insn<big_endian>(p, mflr_12), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, bcl_20_31), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, mflr_11), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, ld_2_11 + l(-16)), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, mtlr_12), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, add_11_2_11), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, ld_12_11 + 0), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, ld_2_11 + 8), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, mtctr_12), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, ld_11_11 + 16), p += 4;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ else
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ write_insn<big_endian>(p, mflr_0), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, bcl_20_31), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, mflr_11), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, ld_2_11 + l(-16)), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, mtlr_0), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, sub_12_12_11), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, add_11_2_11), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, addi_0_12 + l(-48)), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, ld_12_11 + 0), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, srdi_0_0_2), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, mtctr_12), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, ld_11_11 + 8), p += 4;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
write_insn<big_endian>(p, bctr), p += 4;
|
|
|
881b8e |
while (p < oview + this->pltresolve_size)
|
|
|
881b8e |
write_insn<big_endian>(p, nop), p += 4;
|
|
|
881b8e |
@@ -3650,14 +3743,17 @@ Output_data_glink<size, big_endian>::do_write(Output_file* of)
|
|
|
881b8e |
uint32_t indx = 0;
|
|
|
881b8e |
while (p < oview + oview_size)
|
|
|
881b8e |
{
|
|
|
881b8e |
- if (indx < 0x8000)
|
|
|
881b8e |
- {
|
|
|
881b8e |
- write_insn<big_endian>(p, li_0_0 + indx), p += 4;
|
|
|
881b8e |
- }
|
|
|
881b8e |
- else
|
|
|
881b8e |
+ if (this->targ_->abiversion() < 2)
|
|
|
881b8e |
{
|
|
|
881b8e |
- write_insn<big_endian>(p, lis_0_0 + hi(indx)), p += 4;
|
|
|
881b8e |
- write_insn<big_endian>(p, ori_0_0_0 + l(indx)), p += 4;
|
|
|
881b8e |
+ if (indx < 0x8000)
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ write_insn<big_endian>(p, li_0_0 + indx), p += 4;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
+ else
|
|
|
881b8e |
+ {
|
|
|
881b8e |
+ write_insn<big_endian>(p, lis_0_0 + hi(indx)), p += 4;
|
|
|
881b8e |
+ write_insn<big_endian>(p, ori_0_0_0 + l(indx)), p += 4;
|
|
|
881b8e |
+ }
|
|
|
881b8e |
}
|
|
|
881b8e |
uint32_t branch_off = 8 - (p - oview);
|
|
|
881b8e |
write_insn<big_endian>(p, b + (branch_off & 0x3fffffc)), p += 4;
|
|
|
881b8e |
@@ -4144,24 +4240,6 @@ Target_powerpc<size, big_endian>::plt_entry_count() const
|
|
|
881b8e |
return count;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
-// Return the offset of the first non-reserved PLT entry.
|
|
|
881b8e |
-
|
|
|
881b8e |
-template<int size, bool big_endian>
|
|
|
881b8e |
-unsigned int
|
|
|
881b8e |
-Target_powerpc<size, big_endian>::first_plt_entry_offset() const
|
|
|
881b8e |
-{
|
|
|
881b8e |
- return this->plt_->first_plt_entry_offset();
|
|
|
881b8e |
-}
|
|
|
881b8e |
-
|
|
|
881b8e |
-// Return the size of each PLT entry.
|
|
|
881b8e |
-
|
|
|
881b8e |
-template<int size, bool big_endian>
|
|
|
881b8e |
-unsigned int
|
|
|
881b8e |
-Target_powerpc<size, big_endian>::plt_entry_size() const
|
|
|
881b8e |
-{
|
|
|
881b8e |
- return Output_data_plt_powerpc<size, big_endian>::get_plt_entry_size();
|
|
|
881b8e |
-}
|
|
|
881b8e |
-
|
|
|
881b8e |
// Create a GOT entry for local dynamic __tls_get_addr calls.
|
|
|
881b8e |
|
|
|
881b8e |
template<int size, bool big_endian>
|
|
|
881b8e |
@@ -4189,8 +4267,12 @@ Target_powerpc<size, big_endian>::tlsld_got_offset(
|
|
|
881b8e |
|
|
|
881b8e |
template<int size, bool big_endian>
|
|
|
881b8e |
int
|
|
|
881b8e |
-Target_powerpc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
|
|
|
881b8e |
+Target_powerpc<size, big_endian>::Scan::get_reference_flags(
|
|
|
881b8e |
+ unsigned int r_type,
|
|
|
881b8e |
+ const Target_powerpc* target)
|
|
|
881b8e |
{
|
|
|
881b8e |
+ int ref = 0;
|
|
|
881b8e |
+
|
|
|
881b8e |
switch (r_type)
|
|
|
881b8e |
{
|
|
|
881b8e |
case elfcpp::R_POWERPC_NONE:
|
|
|
881b8e |
@@ -4198,7 +4280,7 @@ Target_powerpc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
|
|
|
881b8e |
case elfcpp::R_POWERPC_GNU_VTENTRY:
|
|
|
881b8e |
case elfcpp::R_PPC64_TOC:
|
|
|
881b8e |
// No symbol reference.
|
|
|
881b8e |
- return 0;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
|
|
|
881b8e |
case elfcpp::R_PPC64_ADDR64:
|
|
|
881b8e |
case elfcpp::R_PPC64_UADDR64:
|
|
|
881b8e |
@@ -4209,13 +4291,15 @@ Target_powerpc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
|
|
|
881b8e |
case elfcpp::R_POWERPC_ADDR16_LO:
|
|
|
881b8e |
case elfcpp::R_POWERPC_ADDR16_HI:
|
|
|
881b8e |
case elfcpp::R_POWERPC_ADDR16_HA:
|
|
|
881b8e |
- return Symbol::ABSOLUTE_REF;
|
|
|
881b8e |
+ ref = Symbol::ABSOLUTE_REF;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
|
|
|
881b8e |
case elfcpp::R_POWERPC_ADDR24:
|
|
|
881b8e |
case elfcpp::R_POWERPC_ADDR14:
|
|
|
881b8e |
case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
|
|
|
881b8e |
case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
|
|
|
881b8e |
- return Symbol::FUNCTION_CALL | Symbol::ABSOLUTE_REF;
|
|
|
881b8e |
+ ref = Symbol::FUNCTION_CALL | Symbol::ABSOLUTE_REF;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
|
|
|
881b8e |
case elfcpp::R_PPC64_REL64:
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL32:
|
|
|
881b8e |
@@ -4224,14 +4308,16 @@ Target_powerpc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL16_LO:
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL16_HI:
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL16_HA:
|
|
|
881b8e |
- return Symbol::RELATIVE_REF;
|
|
|
881b8e |
+ ref = Symbol::RELATIVE_REF;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL24:
|
|
|
881b8e |
case elfcpp::R_PPC_PLTREL24:
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL14:
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL14_BRTAKEN:
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL14_BRNTAKEN:
|
|
|
881b8e |
- return Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
|
|
|
881b8e |
+ ref = Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
|
|
|
881b8e |
case elfcpp::R_POWERPC_GOT16:
|
|
|
881b8e |
case elfcpp::R_POWERPC_GOT16_LO:
|
|
|
881b8e |
@@ -4246,11 +4332,13 @@ Target_powerpc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
|
|
|
881b8e |
case elfcpp::R_PPC64_TOC16_DS:
|
|
|
881b8e |
case elfcpp::R_PPC64_TOC16_LO_DS:
|
|
|
881b8e |
// Absolute in GOT.
|
|
|
881b8e |
- return Symbol::ABSOLUTE_REF;
|
|
|
881b8e |
+ ref = Symbol::ABSOLUTE_REF;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
|
|
|
881b8e |
case elfcpp::R_POWERPC_GOT_TPREL16:
|
|
|
881b8e |
case elfcpp::R_POWERPC_TLS:
|
|
|
881b8e |
- return Symbol::TLS_REF;
|
|
|
881b8e |
+ ref = Symbol::TLS_REF;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
|
|
|
881b8e |
case elfcpp::R_POWERPC_COPY:
|
|
|
881b8e |
case elfcpp::R_POWERPC_GLOB_DAT:
|
|
|
881b8e |
@@ -4259,8 +4347,12 @@ Target_powerpc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
|
|
|
881b8e |
case elfcpp::R_POWERPC_DTPMOD:
|
|
|
881b8e |
default:
|
|
|
881b8e |
// Not expected. We will give an error later.
|
|
|
881b8e |
- return 0;
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
}
|
|
|
881b8e |
+
|
|
|
881b8e |
+ if (size == 64 && target->abiversion() < 2)
|
|
|
881b8e |
+ ref |= Symbol::FUNC_DESC_ABI;
|
|
|
881b8e |
+ return ref;
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
// Report an unsupported relocation against a local symbol.
|
|
|
881b8e |
@@ -4331,6 +4423,8 @@ Target_powerpc<size, big_endian>::Scan::check_non_pic(Relobj* object,
|
|
|
881b8e |
case elfcpp::R_PPC64_JMP_IREL:
|
|
|
881b8e |
case elfcpp::R_PPC64_ADDR16_DS:
|
|
|
881b8e |
case elfcpp::R_PPC64_ADDR16_LO_DS:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_ADDR16_HIGH:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_ADDR16_HIGHA:
|
|
|
881b8e |
case elfcpp::R_PPC64_ADDR16_HIGHER:
|
|
|
881b8e |
case elfcpp::R_PPC64_ADDR16_HIGHEST:
|
|
|
881b8e |
case elfcpp::R_PPC64_ADDR16_HIGHERA:
|
|
|
881b8e |
@@ -4339,6 +4433,8 @@ Target_powerpc<size, big_endian>::Scan::check_non_pic(Relobj* object,
|
|
|
881b8e |
case elfcpp::R_POWERPC_ADDR30:
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_DS:
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_LO_DS:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TPREL16_HIGH:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TPREL16_HIGHA:
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_HIGHER:
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_HIGHEST:
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_HIGHERA:
|
|
|
881b8e |
@@ -4509,7 +4605,6 @@ Target_powerpc<size, big_endian>::Scan::local(
|
|
|
881b8e |
case elfcpp::R_POWERPC_GNU_VTINHERIT:
|
|
|
881b8e |
case elfcpp::R_POWERPC_GNU_VTENTRY:
|
|
|
881b8e |
case elfcpp::R_PPC64_TOCSAVE:
|
|
|
881b8e |
- case elfcpp::R_PPC_EMB_MRKREF:
|
|
|
881b8e |
case elfcpp::R_POWERPC_TLS:
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
@@ -4546,6 +4641,8 @@ Target_powerpc<size, big_endian>::Scan::local(
|
|
|
881b8e |
case elfcpp::R_POWERPC_ADDR16_HI:
|
|
|
881b8e |
case elfcpp::R_POWERPC_ADDR16_HA:
|
|
|
881b8e |
case elfcpp::R_POWERPC_UADDR16:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_ADDR16_HIGH:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_ADDR16_HIGHA:
|
|
|
881b8e |
case elfcpp::R_PPC64_ADDR16_HIGHER:
|
|
|
881b8e |
case elfcpp::R_PPC64_ADDR16_HIGHERA:
|
|
|
881b8e |
case elfcpp::R_PPC64_ADDR16_HIGHEST:
|
|
|
881b8e |
@@ -4612,31 +4709,35 @@ Target_powerpc<size, big_endian>::Scan::local(
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL16_HI:
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL16_HA:
|
|
|
881b8e |
case elfcpp::R_POWERPC_SECTOFF:
|
|
|
881b8e |
- case elfcpp::R_POWERPC_TPREL16:
|
|
|
881b8e |
- case elfcpp::R_POWERPC_DTPREL16:
|
|
|
881b8e |
case elfcpp::R_POWERPC_SECTOFF_LO:
|
|
|
881b8e |
- case elfcpp::R_POWERPC_TPREL16_LO:
|
|
|
881b8e |
- case elfcpp::R_POWERPC_DTPREL16_LO:
|
|
|
881b8e |
case elfcpp::R_POWERPC_SECTOFF_HI:
|
|
|
881b8e |
- case elfcpp::R_POWERPC_TPREL16_HI:
|
|
|
881b8e |
- case elfcpp::R_POWERPC_DTPREL16_HI:
|
|
|
881b8e |
case elfcpp::R_POWERPC_SECTOFF_HA:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_SECTOFF_DS:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_SECTOFF_LO_DS:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_TPREL16:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_TPREL16_LO:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_TPREL16_HI:
|
|
|
881b8e |
case elfcpp::R_POWERPC_TPREL16_HA:
|
|
|
881b8e |
- case elfcpp::R_POWERPC_DTPREL16_HA:
|
|
|
881b8e |
- case elfcpp::R_PPC64_DTPREL16_HIGHER:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TPREL16_DS:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TPREL16_LO_DS:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TPREL16_HIGH:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TPREL16_HIGHA:
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_HIGHER:
|
|
|
881b8e |
- case elfcpp::R_PPC64_DTPREL16_HIGHERA:
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_HIGHERA:
|
|
|
881b8e |
- case elfcpp::R_PPC64_DTPREL16_HIGHEST:
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_HIGHEST:
|
|
|
881b8e |
- case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_HIGHESTA:
|
|
|
881b8e |
- case elfcpp::R_PPC64_TPREL16_DS:
|
|
|
881b8e |
- case elfcpp::R_PPC64_TPREL16_LO_DS:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_DTPREL16:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_DTPREL16_LO:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_DTPREL16_HI:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_DTPREL16_HA:
|
|
|
881b8e |
case elfcpp::R_PPC64_DTPREL16_DS:
|
|
|
881b8e |
case elfcpp::R_PPC64_DTPREL16_LO_DS:
|
|
|
881b8e |
- case elfcpp::R_PPC64_SECTOFF_DS:
|
|
|
881b8e |
- case elfcpp::R_PPC64_SECTOFF_LO_DS:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGH:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGHA:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGHER:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGHERA:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGHEST:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
|
|
|
881b8e |
case elfcpp::R_PPC64_TLSGD:
|
|
|
881b8e |
case elfcpp::R_PPC64_TLSLD:
|
|
|
881b8e |
break;
|
|
|
881b8e |
@@ -4870,7 +4971,6 @@ Target_powerpc<size, big_endian>::Scan::global(
|
|
|
881b8e |
case elfcpp::R_POWERPC_GNU_VTINHERIT:
|
|
|
881b8e |
case elfcpp::R_POWERPC_GNU_VTENTRY:
|
|
|
881b8e |
case elfcpp::R_PPC_LOCAL24PC:
|
|
|
881b8e |
- case elfcpp::R_PPC_EMB_MRKREF:
|
|
|
881b8e |
case elfcpp::R_POWERPC_TLS:
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
@@ -4919,6 +5019,8 @@ Target_powerpc<size, big_endian>::Scan::global(
|
|
|
881b8e |
case elfcpp::R_POWERPC_ADDR16_HI:
|
|
|
881b8e |
case elfcpp::R_POWERPC_ADDR16_HA:
|
|
|
881b8e |
case elfcpp::R_POWERPC_UADDR16:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_ADDR16_HIGH:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_ADDR16_HIGHA:
|
|
|
881b8e |
case elfcpp::R_PPC64_ADDR16_HIGHER:
|
|
|
881b8e |
case elfcpp::R_PPC64_ADDR16_HIGHERA:
|
|
|
881b8e |
case elfcpp::R_PPC64_ADDR16_HIGHEST:
|
|
|
881b8e |
@@ -5005,7 +5107,7 @@ Target_powerpc<size, big_endian>::Scan::global(
|
|
|
881b8e |
case elfcpp::R_PPC64_REL64:
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL32:
|
|
|
881b8e |
// Make a dynamic relocation if necessary.
|
|
|
881b8e |
- if (needs_dynamic_reloc<size>(gsym, Scan::get_reference_flags(r_type)))
|
|
|
881b8e |
+ if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type, target)))
|
|
|
881b8e |
{
|
|
|
881b8e |
if (gsym->may_need_copy_reloc())
|
|
|
881b8e |
{
|
|
|
881b8e |
@@ -5037,31 +5139,35 @@ Target_powerpc<size, big_endian>::Scan::global(
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL16_HI:
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL16_HA:
|
|
|
881b8e |
case elfcpp::R_POWERPC_SECTOFF:
|
|
|
881b8e |
- case elfcpp::R_POWERPC_TPREL16:
|
|
|
881b8e |
- case elfcpp::R_POWERPC_DTPREL16:
|
|
|
881b8e |
case elfcpp::R_POWERPC_SECTOFF_LO:
|
|
|
881b8e |
- case elfcpp::R_POWERPC_TPREL16_LO:
|
|
|
881b8e |
- case elfcpp::R_POWERPC_DTPREL16_LO:
|
|
|
881b8e |
case elfcpp::R_POWERPC_SECTOFF_HI:
|
|
|
881b8e |
- case elfcpp::R_POWERPC_TPREL16_HI:
|
|
|
881b8e |
- case elfcpp::R_POWERPC_DTPREL16_HI:
|
|
|
881b8e |
case elfcpp::R_POWERPC_SECTOFF_HA:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_SECTOFF_DS:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_SECTOFF_LO_DS:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_TPREL16:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_TPREL16_LO:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_TPREL16_HI:
|
|
|
881b8e |
case elfcpp::R_POWERPC_TPREL16_HA:
|
|
|
881b8e |
- case elfcpp::R_POWERPC_DTPREL16_HA:
|
|
|
881b8e |
- case elfcpp::R_PPC64_DTPREL16_HIGHER:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TPREL16_DS:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TPREL16_LO_DS:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TPREL16_HIGH:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TPREL16_HIGHA:
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_HIGHER:
|
|
|
881b8e |
- case elfcpp::R_PPC64_DTPREL16_HIGHERA:
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_HIGHERA:
|
|
|
881b8e |
- case elfcpp::R_PPC64_DTPREL16_HIGHEST:
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_HIGHEST:
|
|
|
881b8e |
- case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_HIGHESTA:
|
|
|
881b8e |
- case elfcpp::R_PPC64_TPREL16_DS:
|
|
|
881b8e |
- case elfcpp::R_PPC64_TPREL16_LO_DS:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_DTPREL16:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_DTPREL16_LO:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_DTPREL16_HI:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_DTPREL16_HA:
|
|
|
881b8e |
case elfcpp::R_PPC64_DTPREL16_DS:
|
|
|
881b8e |
case elfcpp::R_PPC64_DTPREL16_LO_DS:
|
|
|
881b8e |
- case elfcpp::R_PPC64_SECTOFF_DS:
|
|
|
881b8e |
- case elfcpp::R_PPC64_SECTOFF_LO_DS:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGH:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGHA:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGHER:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGHERA:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGHEST:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
|
|
|
881b8e |
case elfcpp::R_PPC64_TLSGD:
|
|
|
881b8e |
case elfcpp::R_PPC64_TLSLD:
|
|
|
881b8e |
break;
|
|
|
881b8e |
@@ -5794,7 +5900,8 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
|
|
|
881b8e |
&& (insn2 == nop
|
|
|
881b8e |
|| insn2 == cror_15_15_15 || insn2 == cror_31_31_31))
|
|
|
881b8e |
{
|
|
|
881b8e |
- elfcpp::Swap<32, big_endian>::writeval(wv + 1, ld_2_1 + 40);
|
|
|
881b8e |
+ elfcpp::Swap<32, big_endian>::
|
|
|
881b8e |
+ writeval(wv + 1, ld_2_1 + target->stk_toc());
|
|
|
881b8e |
can_plt_call = true;
|
|
|
881b8e |
}
|
|
|
881b8e |
}
|
|
|
881b8e |
@@ -6083,6 +6190,10 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
|
|
|
881b8e |
if (r_type != elfcpp::R_PPC_PLTREL24)
|
|
|
881b8e |
addend = rela.get_r_addend();
|
|
|
881b8e |
value = psymval->value(object, addend);
|
|
|
881b8e |
+ if (gsym != NULL)
|
|
|
881b8e |
+ value += object->ppc64_local_entry_offset(gsym);
|
|
|
881b8e |
+ else
|
|
|
881b8e |
+ value += object->ppc64_local_entry_offset(r_sym);
|
|
|
881b8e |
if (size == 64 && is_branch_reloc(r_type))
|
|
|
881b8e |
value = target->symval_for_branch(value, gsym, object, &dest_shndx);
|
|
|
881b8e |
unsigned int max_branch_offset = 0;
|
|
|
881b8e |
@@ -6146,8 +6257,10 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
|
|
|
881b8e |
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_DS:
|
|
|
881b8e |
case elfcpp::R_PPC64_TPREL16_LO_DS:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TPREL16_HIGH:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TPREL16_HIGHA:
|
|
|
881b8e |
if (size != 64)
|
|
|
881b8e |
- // R_PPC_TLSGD and R_PPC_TLSLD
|
|
|
881b8e |
+ // R_PPC_TLSGD, R_PPC_TLSLD, R_PPC_EMB_RELST_LO, R_PPC_EMB_RELST_HI
|
|
|
881b8e |
break;
|
|
|
881b8e |
case elfcpp::R_POWERPC_TPREL16:
|
|
|
881b8e |
case elfcpp::R_POWERPC_TPREL16_LO:
|
|
|
881b8e |
@@ -6177,6 +6290,8 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
|
|
|
881b8e |
case elfcpp::R_POWERPC_DTPREL16_HI:
|
|
|
881b8e |
case elfcpp::R_POWERPC_DTPREL16_HA:
|
|
|
881b8e |
case elfcpp::R_POWERPC_DTPREL:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGH:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGHA:
|
|
|
881b8e |
// tls symbol values are relative to tls_segment()->vaddr()
|
|
|
881b8e |
value -= dtp_offset;
|
|
|
881b8e |
break;
|
|
|
881b8e |
@@ -6317,6 +6432,34 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
|
|
|
881b8e |
overflow = Reloc::CHECK_BITFIELD;
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_ADDR16_HI:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_ADDR16_HA:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_GOT16_HI:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_GOT16_HA:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_PLT16_HI:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_PLT16_HA:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_SECTOFF_HI:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_SECTOFF_HA:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TOC16_HI:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TOC16_HA:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_PLTGOT16_HI:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_PLTGOT16_HA:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_TPREL16_HI:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_TPREL16_HA:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_DTPREL16_HI:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_DTPREL16_HA:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_GOT_TLSGD16_HI:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_GOT_TLSGD16_HA:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_GOT_TLSLD16_HI:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_GOT_TLSLD16_HA:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_GOT_TPREL16_HI:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_GOT_TPREL16_HA:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_GOT_DTPREL16_HI:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_GOT_DTPREL16_HA:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_REL16_HI:
|
|
|
881b8e |
+ case elfcpp::R_POWERPC_REL16_HA:
|
|
|
881b8e |
+ if (size == 32)
|
|
|
881b8e |
+ break;
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL24:
|
|
|
881b8e |
case elfcpp::R_PPC_PLTREL24:
|
|
|
881b8e |
case elfcpp::R_PPC_LOCAL24PC:
|
|
|
881b8e |
@@ -6350,7 +6493,6 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
|
|
|
881b8e |
case elfcpp::R_POWERPC_TLS:
|
|
|
881b8e |
case elfcpp::R_POWERPC_GNU_VTINHERIT:
|
|
|
881b8e |
case elfcpp::R_POWERPC_GNU_VTENTRY:
|
|
|
881b8e |
- case elfcpp::R_PPC_EMB_MRKREF:
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
case elfcpp::R_PPC64_ADDR64:
|
|
|
881b8e |
@@ -6421,6 +6563,12 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
|
|
|
881b8e |
status = Reloc::addr16_u(view, value, overflow);
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
+ case elfcpp::R_PPC64_ADDR16_HIGH:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TPREL16_HIGH:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGH:
|
|
|
881b8e |
+ if (size == 32)
|
|
|
881b8e |
+ // R_PPC_EMB_MRKREF, R_PPC_EMB_RELST_LO, R_PPC_EMB_RELST_HA
|
|
|
881b8e |
+ goto unsupp;
|
|
|
881b8e |
case elfcpp::R_POWERPC_ADDR16_HI:
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL16_HI:
|
|
|
881b8e |
case elfcpp::R_PPC64_TOC16_HI:
|
|
|
881b8e |
@@ -6435,6 +6583,12 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
|
|
|
881b8e |
Reloc::addr16_hi(view, value);
|
|
|
881b8e |
break;
|
|
|
881b8e |
|
|
|
881b8e |
+ case elfcpp::R_PPC64_ADDR16_HIGHA:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_TPREL16_HIGHA:
|
|
|
881b8e |
+ case elfcpp::R_PPC64_DTPREL16_HIGHA:
|
|
|
881b8e |
+ if (size == 32)
|
|
|
881b8e |
+ // R_PPC_EMB_RELSEC16, R_PPC_EMB_RELST_HI, R_PPC_EMB_BIT_FLD
|
|
|
881b8e |
+ goto unsupp;
|
|
|
881b8e |
case elfcpp::R_POWERPC_ADDR16_HA:
|
|
|
881b8e |
case elfcpp::R_POWERPC_REL16_HA:
|
|
|
881b8e |
case elfcpp::R_PPC64_TOC16_HA:
|
|
|
881b8e |
@@ -6559,11 +6713,6 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
|
|
|
881b8e |
case elfcpp::R_PPC64_PLT16_LO_DS:
|
|
|
881b8e |
case elfcpp::R_PPC64_PLTGOT16_DS:
|
|
|
881b8e |
case elfcpp::R_PPC64_PLTGOT16_LO_DS:
|
|
|
881b8e |
- case elfcpp::R_PPC_EMB_RELSEC16:
|
|
|
881b8e |
- case elfcpp::R_PPC_EMB_RELST_LO:
|
|
|
881b8e |
- case elfcpp::R_PPC_EMB_RELST_HI:
|
|
|
881b8e |
- case elfcpp::R_PPC_EMB_RELST_HA:
|
|
|
881b8e |
- case elfcpp::R_PPC_EMB_BIT_FLD:
|
|
|
881b8e |
case elfcpp::R_PPC_EMB_RELSDA:
|
|
|
881b8e |
case elfcpp::R_PPC_TOC16:
|
|
|
881b8e |
default:
|
|
|
881b8e |
diff --git a/gold/symtab.h b/gold/symtab.h
|
|
|
881b8e |
index f26d4b9..457b8bd 100644
|
|
|
881b8e |
--- a/gold/symtab.h
|
|
|
881b8e |
+++ b/gold/symtab.h
|
|
|
881b8e |
@@ -634,7 +634,10 @@ class Symbol
|
|
|
881b8e |
// A TLS-related reference.
|
|
|
881b8e |
TLS_REF = 4,
|
|
|
881b8e |
// A reference that can always be treated as a function call.
|
|
|
881b8e |
- FUNCTION_CALL = 8
|
|
|
881b8e |
+ FUNCTION_CALL = 8,
|
|
|
881b8e |
+ // When set, says that dynamic relocations are needed even if a
|
|
|
881b8e |
+ // symbol has a plt entry.
|
|
|
881b8e |
+ FUNC_DESC_ABI = 16,
|
|
|
881b8e |
};
|
|
|
881b8e |
|
|
|
881b8e |
// Given a direct absolute or pc-relative static relocation against
|
|
|
881b8e |
@@ -671,7 +674,8 @@ class Symbol
|
|
|
881b8e |
|
|
|
881b8e |
// A reference to any PLT entry in a non-position-independent executable
|
|
|
881b8e |
// does not need a dynamic relocation.
|
|
|
881b8e |
- if (!parameters->options().output_is_position_independent()
|
|
|
881b8e |
+ if (!(flags & FUNC_DESC_ABI)
|
|
|
881b8e |
+ && !parameters->options().output_is_position_independent()
|
|
|
881b8e |
&& this->has_plt_offset())
|
|
|
881b8e |
return false;
|
|
|
881b8e |
|
|
|
881b8e |
diff --git a/include/elf/ppc.h b/include/elf/ppc.h
|
|
|
881b8e |
index f80a1e8..da00df8 100644
|
|
|
881b8e |
--- a/include/elf/ppc.h
|
|
|
881b8e |
+++ b/include/elf/ppc.h
|
|
|
881b8e |
@@ -176,7 +176,8 @@ END_RELOC_NUMBERS (R_PPC_max)
|
|
|
881b8e |
#define DT_PPC_GOT (DT_LOPROC)
|
|
|
881b8e |
|
|
|
881b8e |
/* Specify that tls descriptors should be optimized. */
|
|
|
881b8e |
-#define DT_PPC_TLSOPT (DT_LOPROC + 1)
|
|
|
881b8e |
+#define DT_PPC_OPT (DT_LOPROC + 1)
|
|
|
881b8e |
+#define PPC_OPT_TLS 1
|
|
|
881b8e |
|
|
|
881b8e |
/* Processor specific flags for the ELF header e_flags field. */
|
|
|
881b8e |
|
|
|
881b8e |
diff --git a/include/elf/ppc64.h b/include/elf/ppc64.h
|
|
|
881b8e |
index f1c80f1..78d947b 100644
|
|
|
881b8e |
--- a/include/elf/ppc64.h
|
|
|
881b8e |
+++ b/include/elf/ppc64.h
|
|
|
881b8e |
@@ -141,6 +141,14 @@ START_RELOC_NUMBERS (elf_ppc64_reloc_type)
|
|
|
881b8e |
RELOC_NUMBER (R_PPC64_TLSLD, 108)
|
|
|
881b8e |
RELOC_NUMBER (R_PPC64_TOCSAVE, 109)
|
|
|
881b8e |
|
|
|
881b8e |
+/* Added when HA and HI relocs were changed to report overflows. */
|
|
|
881b8e |
+ RELOC_NUMBER (R_PPC64_ADDR16_HIGH, 110)
|
|
|
881b8e |
+ RELOC_NUMBER (R_PPC64_ADDR16_HIGHA, 111)
|
|
|
881b8e |
+ RELOC_NUMBER (R_PPC64_TPREL16_HIGH, 112)
|
|
|
881b8e |
+ RELOC_NUMBER (R_PPC64_TPREL16_HIGHA, 113)
|
|
|
881b8e |
+ RELOC_NUMBER (R_PPC64_DTPREL16_HIGH, 114)
|
|
|
881b8e |
+ RELOC_NUMBER (R_PPC64_DTPREL16_HIGHA, 115)
|
|
|
881b8e |
+
|
|
|
881b8e |
#ifndef RELOC_MACROS_GEN_FUNC
|
|
|
881b8e |
/* Fake relocation only used internally by ld. */
|
|
|
881b8e |
RELOC_NUMBER (R_PPC64_LO_DS_OPT, 128)
|
|
|
881b8e |
@@ -161,8 +169,63 @@ START_RELOC_NUMBERS (elf_ppc64_reloc_type)
|
|
|
881b8e |
|
|
|
881b8e |
END_RELOC_NUMBERS (R_PPC64_max)
|
|
|
881b8e |
|
|
|
881b8e |
-#define IS_PPC64_TLS_RELOC(R) \
|
|
|
881b8e |
- ((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA)
|
|
|
881b8e |
+#define IS_PPC64_TLS_RELOC(R) \
|
|
|
881b8e |
+ (((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA) \
|
|
|
881b8e |
+ || ((R) >= R_PPC64_TPREL16_HIGH && (R) <= R_PPC64_DTPREL16_HIGHA))
|
|
|
881b8e |
+
|
|
|
881b8e |
+
|
|
|
881b8e |
+/* e_flags bits specifying ABI.
|
|
|
881b8e |
+ 1 for original function descriptor using ABI,
|
|
|
881b8e |
+ 2 for revised ABI without function descriptors,
|
|
|
881b8e |
+ 0 for unspecified or not using any features affected by the differences. */
|
|
|
881b8e |
+#define EF_PPC64_ABI 3
|
|
|
881b8e |
+
|
|
|
881b8e |
+/* The ELFv2 ABI uses three bits in the symbol st_other field of a
|
|
|
881b8e |
+ function definition to specify the number of instructions between a
|
|
|
881b8e |
+ function's global entry point and local entry point.
|
|
|
881b8e |
+ The global entry point is used when it is necessary to set up the
|
|
|
881b8e |
+ toc pointer (r2) for the function. Callers must enter the global
|
|
|
881b8e |
+ entry point with r12 set to the global entry point address. On
|
|
|
881b8e |
+ return from the function, r2 may have a different value to that
|
|
|
881b8e |
+ which it had on entry.
|
|
|
881b8e |
+ The local entry point is used when r2 is known to already be valid
|
|
|
881b8e |
+ for the function. There is no requirement on r12 when using the
|
|
|
881b8e |
+ local entry point, and on return r2 will contain the same value as
|
|
|
881b8e |
+ at entry.
|
|
|
881b8e |
+ A value of zero in these bits means that the function has a single
|
|
|
881b8e |
+ entry point with no requirement on r12 or r2, and that on return r2
|
|
|
881b8e |
+ will contain the same value as at entry.
|
|
|
881b8e |
+ Values of one and seven are reserved. */
|
|
|
881b8e |
+#define STO_PPC64_LOCAL_BIT 5
|
|
|
881b8e |
+#define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT)
|
|
|
881b8e |
+
|
|
|
881b8e |
+// 3 bit other field to bytes.
|
|
|
881b8e |
+static inline unsigned int
|
|
|
881b8e |
+ppc64_decode_local_entry(unsigned int other)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ return ((1 << other) >> 2) << 2;
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
+// bytes to field value.
|
|
|
881b8e |
+static inline unsigned int
|
|
|
881b8e |
+ppc64_encode_local_entry(unsigned int val)
|
|
|
881b8e |
+{
|
|
|
881b8e |
+ return (val >= 4 * 4
|
|
|
881b8e |
+ ? (val >= 8 * 4
|
|
|
881b8e |
+ ? (val >= 16 * 4 ? 6 : 5)
|
|
|
881b8e |
+ : 4)
|
|
|
881b8e |
+ : (val >= 2 * 4
|
|
|
881b8e |
+ ? 3
|
|
|
881b8e |
+ : (val >= 1 * 4 ? 2 : 0)));
|
|
|
881b8e |
+}
|
|
|
881b8e |
+
|
|
|
881b8e |
+/* st_other to number of bytes. */
|
|
|
881b8e |
+#define PPC64_LOCAL_ENTRY_OFFSET(other) \
|
|
|
881b8e |
+ ppc64_decode_local_entry (((other) & STO_PPC64_LOCAL_MASK) \
|
|
|
881b8e |
+ >> STO_PPC64_LOCAL_BIT)
|
|
|
881b8e |
+/* number of bytes to st_other. */
|
|
|
881b8e |
+#define PPC64_SET_LOCAL_ENTRY_OFFSET(val) \
|
|
|
881b8e |
+ ppc64_encode_local_entry (val) << STO_PPC64_LOCAL_BIT
|
|
|
881b8e |
|
|
|
881b8e |
/* Specify the start of the .glink section. */
|
|
|
881b8e |
#define DT_PPC64_GLINK DT_LOPROC
|
|
|
881b8e |
@@ -171,7 +234,9 @@ END_RELOC_NUMBERS (R_PPC64_max)
|
|
|
881b8e |
#define DT_PPC64_OPD (DT_LOPROC + 1)
|
|
|
881b8e |
#define DT_PPC64_OPDSZ (DT_LOPROC + 2)
|
|
|
881b8e |
|
|
|
881b8e |
-/* Specify that tls descriptors should be optimized. */
|
|
|
881b8e |
-#define DT_PPC64_TLSOPT (DT_LOPROC + 3)
|
|
|
881b8e |
+/* Specify whether various optimisations are possible. */
|
|
|
881b8e |
+#define DT_PPC64_OPT (DT_LOPROC + 3)
|
|
|
881b8e |
+#define PPC64_OPT_TLS 1
|
|
|
881b8e |
+#define PPC64_OPT_MULTI_TOC 2
|
|
|
881b8e |
|
|
|
881b8e |
#endif /* _ELF_PPC64_H */
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-elfvers/vers24.rd b/ld/testsuite/ld-elfvers/vers24.rd
|
|
|
881b8e |
index 42e81e4..fb464f9 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-elfvers/vers24.rd
|
|
|
881b8e |
+++ b/ld/testsuite/ld-elfvers/vers24.rd
|
|
|
881b8e |
@@ -7,9 +7,9 @@ Symbol table '.dynsym' contains [0-9]+ entries:
|
|
|
881b8e |
# And ensure the dynamic symbol table contains at least x@VERS.0
|
|
|
881b8e |
# and foo@@VERS.0 symbols
|
|
|
881b8e |
#...
|
|
|
881b8e |
- +[0-9]+: [0-9a-f]+ +(4 +OBJECT +GLOBAL +DEFAULT +[0-9]+ _?x|[0-9]+ +FUNC +GLOBAL +DEFAULT +[0-9]+ _?foo@)@VERS\.0
|
|
|
881b8e |
+ +[0-9]+: [0-9a-f]+ +(4 +OBJECT +GLOBAL +DEFAULT +[0-9]+ _?x|[0-9]+ +FUNC +GLOBAL +DEFAULT .* [0-9]+ _?foo@)@VERS\.0
|
|
|
881b8e |
#...
|
|
|
881b8e |
- +[0-9]+: [0-9a-f]+ +(4 +OBJECT +GLOBAL +DEFAULT +[0-9]+ _?x|[0-9]+ +FUNC +GLOBAL +DEFAULT +[0-9]+ _?foo@)@VERS\.0
|
|
|
881b8e |
+ +[0-9]+: [0-9a-f]+ +(4 +OBJECT +GLOBAL +DEFAULT +[0-9]+ _?x|[0-9]+ +FUNC +GLOBAL +DEFAULT .* [0-9]+ _?foo@)@VERS\.0
|
|
|
881b8e |
#...
|
|
|
881b8e |
Symbol table '.symtab' contains [0-9]+ entries:
|
|
|
881b8e |
#pass
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-ifunc/ifunc.exp b/ld/testsuite/ld-ifunc/ifunc.exp
|
|
|
881b8e |
index df913d8..d4c4035 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-ifunc/ifunc.exp
|
|
|
881b8e |
+++ b/ld/testsuite/ld-ifunc/ifunc.exp
|
|
|
881b8e |
@@ -97,8 +97,9 @@ proc contains_ifunc_symbol { binary_file } {
|
|
|
881b8e |
|
|
|
881b8e |
# Look for a line like this:
|
|
|
881b8e |
# 58: 0000000000400600 30 IFUNC GLOBAL DEFAULT 12 library_func2
|
|
|
881b8e |
+ # with perhaps some other info between the visibility and section
|
|
|
881b8e |
|
|
|
881b8e |
- if { ![regexp ".*\[ \]*IFUNC\[ \]+GLOBAL\[ \]+DEFAULT\[ \]+\[UND0-9\]+\[ \]+library_func2\n" [file_contents readelf.out]] } {
|
|
|
881b8e |
+ if { ![regexp ".*\[ \]*IFUNC\[ \]+GLOBAL\[ \]+DEFAULT .* \[UND0-9\]+\[ \]+library_func2\n" [file_contents readelf.out]] } {
|
|
|
881b8e |
return 0
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/elfv2.s b/ld/testsuite/ld-powerpc/elfv2.s
|
|
|
881b8e |
new file mode 100644
|
|
|
881b8e |
index 0000000..c2a4c3b
|
|
|
881b8e |
--- /dev/null
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/elfv2.s
|
|
|
881b8e |
@@ -0,0 +1,32 @@
|
|
|
881b8e |
+ .section .toc,"aw",@progbits
|
|
|
881b8e |
+.L0:
|
|
|
881b8e |
+ .quad x
|
|
|
881b8e |
+
|
|
|
881b8e |
+ .data
|
|
|
881b8e |
+x:
|
|
|
881b8e |
+ .quad f1
|
|
|
881b8e |
+
|
|
|
881b8e |
+ .globl f1
|
|
|
881b8e |
+ .type f1,@function
|
|
|
881b8e |
+ .text
|
|
|
881b8e |
+f1:
|
|
|
881b8e |
+ addis 2,12,.TOC.-f1@ha
|
|
|
881b8e |
+ addi 2,2,.TOC.-f1@l
|
|
|
881b8e |
+ .localentry f1,.-f1
|
|
|
881b8e |
+ mflr 0
|
|
|
881b8e |
+ stdu 1,-32(1)
|
|
|
881b8e |
+ std 0,48(1)
|
|
|
881b8e |
+ bl f1
|
|
|
881b8e |
+ ld 3,.L0@toc(2)
|
|
|
881b8e |
+ bl f2
|
|
|
881b8e |
+ nop
|
|
|
881b8e |
+ ld 3,x@got(2)
|
|
|
881b8e |
+ bl f3
|
|
|
881b8e |
+ nop
|
|
|
881b8e |
+ bl f4
|
|
|
881b8e |
+ nop
|
|
|
881b8e |
+ ld 0,48(1)
|
|
|
881b8e |
+ addi 1,1,32
|
|
|
881b8e |
+ mtlr 0
|
|
|
881b8e |
+ blr
|
|
|
881b8e |
+ .size f1,.-f1
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/elfv2exe.d b/ld/testsuite/ld-powerpc/elfv2exe.d
|
|
|
881b8e |
new file mode 100644
|
|
|
881b8e |
index 0000000..7ff9d38
|
|
|
881b8e |
--- /dev/null
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/elfv2exe.d
|
|
|
881b8e |
@@ -0,0 +1,40 @@
|
|
|
881b8e |
+#source: elfv2.s
|
|
|
881b8e |
+#as: -a64
|
|
|
881b8e |
+#ld: -melf64ppc --defsym f2=0x1234 --defsym f3=0x10008888 --defsym f4=0x1200000 --defsym _start=f1
|
|
|
881b8e |
+#objdump: -dr
|
|
|
881b8e |
+
|
|
|
881b8e |
+.*
|
|
|
881b8e |
+
|
|
|
881b8e |
+Disassembly of section \.text:
|
|
|
881b8e |
+
|
|
|
881b8e |
+0+100000c0 <.*\.plt_branch\.f2>:
|
|
|
881b8e |
+.*: (ff ff 62 3d|3d 62 ff ff) addis r11,r2,-1
|
|
|
881b8e |
+.*: (f0 7f 8b e9|e9 8b 7f f0) ld r12,32752\(r11\)
|
|
|
881b8e |
+.*: (a6 03 89 7d|7d 89 03 a6) mtctr r12
|
|
|
881b8e |
+.*: (20 04 80 4e|4e 80 04 20) bctr
|
|
|
881b8e |
+
|
|
|
881b8e |
+0+100000d0 <.*\.plt_branch\.f4>:
|
|
|
881b8e |
+.*: (ff ff 62 3d|3d 62 ff ff) addis r11,r2,-1
|
|
|
881b8e |
+.*: (f8 7f 8b e9|e9 8b 7f f8) ld r12,32760\(r11\)
|
|
|
881b8e |
+.*: (a6 03 89 7d|7d 89 03 a6) mtctr r12
|
|
|
881b8e |
+.*: (20 04 80 4e|4e 80 04 20) bctr
|
|
|
881b8e |
+
|
|
|
881b8e |
+0+100000e0 <_start>:
|
|
|
881b8e |
+.*: (02 10 40 3c|3c 40 10 02) lis r2,4098
|
|
|
881b8e |
+.*: (40 81 42 38|38 42 81 40) addi r2,r2,-32448
|
|
|
881b8e |
+.*: (a6 02 08 7c|7c 08 02 a6) mflr r0
|
|
|
881b8e |
+.*: (e1 ff 21 f8|f8 21 ff e1) stdu r1,-32\(r1\)
|
|
|
881b8e |
+.*: (30 00 01 f8|f8 01 00 30) std r0,48\(r1\)
|
|
|
881b8e |
+.*: (f5 ff ff 4b|4b ff ff f5) bl .* <_start\+0x8>
|
|
|
881b8e |
+.*: (08 80 62 e8|e8 62 80 08) ld r3,-32760\(r2\)
|
|
|
881b8e |
+.*: (c5 ff ff 4b|4b ff ff c5) bl .*\.plt_branch\.f2>
|
|
|
881b8e |
+.*: (00 00 00 60|60 00 00 00) nop
|
|
|
881b8e |
+.*: (10 80 62 e8|e8 62 80 10) ld r3,-32752\(r2\)
|
|
|
881b8e |
+.*: (81 87 00 48|48 00 87 81) bl 10008888 <f3>
|
|
|
881b8e |
+.*: (00 00 00 60|60 00 00 00) nop
|
|
|
881b8e |
+.*: (c1 ff ff 4b|4b ff ff c1) bl .*\.plt_branch\.f4>
|
|
|
881b8e |
+.*: (00 00 00 60|60 00 00 00) nop
|
|
|
881b8e |
+.*: (30 00 01 e8|e8 01 00 30) ld r0,48\(r1\)
|
|
|
881b8e |
+.*: (20 00 21 38|38 21 00 20) addi r1,r1,32
|
|
|
881b8e |
+.*: (a6 03 08 7c|7c 08 03 a6) mtlr r0
|
|
|
881b8e |
+.*: (20 00 80 4e|4e 80 00 20) blr
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/elfv2so.d b/ld/testsuite/ld-powerpc/elfv2so.d
|
|
|
881b8e |
new file mode 100644
|
|
|
881b8e |
index 0000000..963dbb6
|
|
|
881b8e |
--- /dev/null
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/elfv2so.d
|
|
|
881b8e |
@@ -0,0 +1,82 @@
|
|
|
881b8e |
+#source: elfv2.s
|
|
|
881b8e |
+#as: -a64
|
|
|
881b8e |
+#ld: -melf64ppc -shared
|
|
|
881b8e |
+#objdump: -dr
|
|
|
881b8e |
+
|
|
|
881b8e |
+.*
|
|
|
881b8e |
+
|
|
|
881b8e |
+Disassembly of section \.text:
|
|
|
881b8e |
+
|
|
|
881b8e |
+0+300 <.*\.plt_call\.f4>:
|
|
|
881b8e |
+.*: (18 00 41 f8|f8 41 00 18) std r2,24\(r1\)
|
|
|
881b8e |
+.*: (38 80 82 e9|e9 82 80 38) ld r12,-32712\(r2\)
|
|
|
881b8e |
+.*: (a6 03 89 7d|7d 89 03 a6) mtctr r12
|
|
|
881b8e |
+.*: (20 04 80 4e|4e 80 04 20) bctr
|
|
|
881b8e |
+
|
|
|
881b8e |
+0+310 <.*\.plt_call\.f3>:
|
|
|
881b8e |
+.*: (18 00 41 f8|f8 41 00 18) std r2,24\(r1\)
|
|
|
881b8e |
+.*: (28 80 82 e9|e9 82 80 28) ld r12,-32728\(r2\)
|
|
|
881b8e |
+.*: (a6 03 89 7d|7d 89 03 a6) mtctr r12
|
|
|
881b8e |
+.*: (20 04 80 4e|4e 80 04 20) bctr
|
|
|
881b8e |
+
|
|
|
881b8e |
+0+320 <.*\.plt_call\.f2>:
|
|
|
881b8e |
+.*: (18 00 41 f8|f8 41 00 18) std r2,24\(r1\)
|
|
|
881b8e |
+.*: (30 80 82 e9|e9 82 80 30) ld r12,-32720\(r2\)
|
|
|
881b8e |
+.*: (a6 03 89 7d|7d 89 03 a6) mtctr r12
|
|
|
881b8e |
+.*: (20 04 80 4e|4e 80 04 20) bctr
|
|
|
881b8e |
+
|
|
|
881b8e |
+0+330 <.*\.plt_call\.f1>:
|
|
|
881b8e |
+.*: (18 00 41 f8|f8 41 00 18) std r2,24\(r1\)
|
|
|
881b8e |
+.*: (40 80 82 e9|e9 82 80 40) ld r12,-32704\(r2\)
|
|
|
881b8e |
+.*: (a6 03 89 7d|7d 89 03 a6) mtctr r12
|
|
|
881b8e |
+.*: (20 04 80 4e|4e 80 04 20) bctr
|
|
|
881b8e |
+
|
|
|
881b8e |
+0+340 <f1>:
|
|
|
881b8e |
+.*: (02 00 4c 3c|3c 4c 00 02) addis r2,r12,2
|
|
|
881b8e |
+.*: (e0 81 42 38|38 42 81 e0) addi r2,r2,-32288
|
|
|
881b8e |
+.*: (a6 02 08 7c|7c 08 02 a6) mflr r0
|
|
|
881b8e |
+.*: (e1 ff 21 f8|f8 21 ff e1) stdu r1,-32\(r1\)
|
|
|
881b8e |
+.*: (30 00 01 f8|f8 01 00 30) std r0,48\(r1\)
|
|
|
881b8e |
+.*: (dd ff ff 4b|4b ff ff dd) bl .*\.plt_call\.f1>
|
|
|
881b8e |
+.*: (08 80 62 e8|e8 62 80 08) ld r3,-32760\(r2\)
|
|
|
881b8e |
+.*: (c5 ff ff 4b|4b ff ff c5) bl .*\.plt_call\.f2>
|
|
|
881b8e |
+.*: (18 00 41 e8|e8 41 00 18) ld r2,24\(r1\)
|
|
|
881b8e |
+.*: (10 80 62 e8|e8 62 80 10) ld r3,-32752\(r2\)
|
|
|
881b8e |
+.*: (a9 ff ff 4b|4b ff ff a9) bl .*\.plt_call\.f3>
|
|
|
881b8e |
+.*: (18 00 41 e8|e8 41 00 18) ld r2,24\(r1\)
|
|
|
881b8e |
+.*: (91 ff ff 4b|4b ff ff 91) bl .*\.plt_call\.f4>
|
|
|
881b8e |
+.*: (18 00 41 e8|e8 41 00 18) ld r2,24\(r1\)
|
|
|
881b8e |
+.*: (30 00 01 e8|e8 01 00 30) ld r0,48\(r1\)
|
|
|
881b8e |
+.*: (20 00 21 38|38 21 00 20) addi r1,r1,32
|
|
|
881b8e |
+.*: (a6 03 08 7c|7c 08 03 a6) mtlr r0
|
|
|
881b8e |
+.*: (20 00 80 4e|4e 80 00 20) blr
|
|
|
881b8e |
+.*: (a0 01 01 00|00 00 00 00) .*
|
|
|
881b8e |
+.*: (00 00 00 00|00 01 01 a0) .*
|
|
|
881b8e |
+
|
|
|
881b8e |
+0+390 <__glink_PLTresolve>:
|
|
|
881b8e |
+.*: (a6 02 08 7c|7c 08 02 a6) mflr r0
|
|
|
881b8e |
+.*: (05 00 9f 42|42 9f 00 05) bcl .*
|
|
|
881b8e |
+.*: (a6 02 68 7d|7d 68 02 a6) mflr r11
|
|
|
881b8e |
+.*: (f0 ff 4b e8|e8 4b ff f0) ld r2,-16\(r11\)
|
|
|
881b8e |
+.*: (a6 03 08 7c|7c 08 03 a6) mtlr r0
|
|
|
881b8e |
+.*: (50 60 8b 7d|7d 8b 60 50) subf r12,r11,r12
|
|
|
881b8e |
+.*: (14 5a 62 7d|7d 62 5a 14) add r11,r2,r11
|
|
|
881b8e |
+.*: (d0 ff 0c 38|38 0c ff d0) addi r0,r12,-48
|
|
|
881b8e |
+.*: (00 00 8b e9|e9 8b 00 00) ld r12,0\(r11\)
|
|
|
881b8e |
+.*: (82 f0 00 78|78 00 f0 82) rldicl r0,r0,62,2
|
|
|
881b8e |
+.*: (a6 03 89 7d|7d 89 03 a6) mtctr r12
|
|
|
881b8e |
+.*: (08 00 6b e9|e9 6b 00 08) ld r11,8\(r11\)
|
|
|
881b8e |
+.*: (20 04 80 4e|4e 80 04 20) bctr
|
|
|
881b8e |
+.*: (00 00 00 60|60 00 00 00) nop
|
|
|
881b8e |
+
|
|
|
881b8e |
+.* <f3@plt>:
|
|
|
881b8e |
+.*: (c8 ff ff 4b|4b ff ff c8) b .* <__glink_PLTresolve>
|
|
|
881b8e |
+
|
|
|
881b8e |
+.* <f2@plt>:
|
|
|
881b8e |
+.*: (c4 ff ff 4b|4b ff ff c4) b .* <__glink_PLTresolve>
|
|
|
881b8e |
+
|
|
|
881b8e |
+.* <f4@plt>:
|
|
|
881b8e |
+.*: (c0 ff ff 4b|4b ff ff c0) b .* <__glink_PLTresolve>
|
|
|
881b8e |
+
|
|
|
881b8e |
+.* <f1@plt>:
|
|
|
881b8e |
+.*: (bc ff ff 4b|4b ff ff bc) b .* <__glink_PLTresolve>
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp
|
|
|
881b8e |
index f022b95..837ad64 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/powerpc.exp
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/powerpc.exp
|
|
|
881b8e |
@@ -269,6 +269,8 @@ run_ld_link_tests $ppcelftests
|
|
|
881b8e |
if [ supports_ppc64 ] then {
|
|
|
881b8e |
run_ld_link_tests $ppc64elftests
|
|
|
881b8e |
run_dump_test "relbrlt"
|
|
|
881b8e |
+ run_dump_test "elfv2so"
|
|
|
881b8e |
+ run_dump_test "elfv2exe"
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
if { [istarget "powerpc*-eabi*"] } {
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tls.d b/ld/testsuite/ld-powerpc/tls.d
|
|
|
881b8e |
index 3c32980..eb4be24 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tls.d
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tls.d
|
|
|
881b8e |
@@ -9,7 +9,7 @@
|
|
|
881b8e |
|
|
|
881b8e |
Disassembly of section \.text:
|
|
|
881b8e |
|
|
|
881b8e |
-0+100000e8 <_start>:
|
|
|
881b8e |
+0+100000e8 <\._start>:
|
|
|
881b8e |
.*: (3c 6d 00 00|00 00 6d 3c) addis r3,r13,0
|
|
|
881b8e |
.*: (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
.*: (38 63 90 78|78 90 63 38) addi r3,r3,-28552
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tls.g b/ld/testsuite/ld-powerpc/tls.g
|
|
|
881b8e |
index 83f8e06..2de9e3b 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tls.g
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tls.g
|
|
|
881b8e |
@@ -8,5 +8,5 @@
|
|
|
881b8e |
.*
|
|
|
881b8e |
|
|
|
881b8e |
Contents of section \.got:
|
|
|
881b8e |
- 100101e0 (00000000|e0810110) (100181e0|00000000) (ffffffff|1880ffff) (ffff8018|ffffffff) .*
|
|
|
881b8e |
- 100101f0 (ffffffff|5880ffff) (ffff8058|ffffffff) .*
|
|
|
881b8e |
+ 100101f8 (00000000|f8810110) (100181f8|00000000) (ffffffff|1880ffff) (ffff8018|ffffffff) .*
|
|
|
881b8e |
+ 10010208 (ffffffff|5880ffff) (ffff8058|ffffffff) .*
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tls.s b/ld/testsuite/ld-powerpc/tls.s
|
|
|
881b8e |
index 5ad9f3d..49828d0 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tls.s
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tls.s
|
|
|
881b8e |
@@ -19,8 +19,13 @@ ie4: .quad 0x56789abcdef01234
|
|
|
881b8e |
le4: .quad 0x6789abcdef012345
|
|
|
881b8e |
le5: .quad 0x789abcdef0123456
|
|
|
881b8e |
|
|
|
881b8e |
- .text
|
|
|
881b8e |
+ .section ".opd","aw",@progbits
|
|
|
881b8e |
+ .p2align 3
|
|
|
881b8e |
_start:
|
|
|
881b8e |
+ .quad .L_start,.TOC.@tocbase,0
|
|
|
881b8e |
+
|
|
|
881b8e |
+ .text
|
|
|
881b8e |
+.L_start:
|
|
|
881b8e |
#extern syms
|
|
|
881b8e |
#GD
|
|
|
881b8e |
addi 3,2,gd@got@tlsgd #R_PPC64_GOT_TLSGD16 gd
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tlsexe.d b/ld/testsuite/ld-powerpc/tlsexe.d
|
|
|
881b8e |
index 8390551..0d5ee40 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tlsexe.d
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tlsexe.d
|
|
|
881b8e |
@@ -19,8 +19,8 @@ Disassembly of section \.text:
|
|
|
881b8e |
.* (7d 68 02 a6|a6 02 68 7d) mflr r11
|
|
|
881b8e |
.* (f9 61 00 20|20 00 61 f9) std r11,32\(r1\)
|
|
|
881b8e |
.* (f8 41 00 28|28 00 41 f8) std r2,40\(r1\)
|
|
|
881b8e |
-.* (e9 62 80 48|48 80 62 e9) ld r11,-32696\(r2\)
|
|
|
881b8e |
-.* (7d 69 03 a6|a6 03 69 7d) mtctr r11
|
|
|
881b8e |
+.* (e9 82 80 48|48 80 82 e9) ld r12,-32696\(r2\)
|
|
|
881b8e |
+.* (7d 89 03 a6|a6 03 89 7d) mtctr r12
|
|
|
881b8e |
.* (e8 42 80 50|50 80 42 e8) ld r2,-32688\(r2\)
|
|
|
881b8e |
.* (4e 80 04 21|21 04 80 4e) bctrl
|
|
|
881b8e |
.* (e9 61 00 20|20 00 61 e9) ld r11,32\(r1\)
|
|
|
881b8e |
@@ -28,7 +28,7 @@ Disassembly of section \.text:
|
|
|
881b8e |
.* (7d 68 03 a6|a6 03 68 7d) mtlr r11
|
|
|
881b8e |
.* (4e 80 00 20|20 00 80 4e) blr
|
|
|
881b8e |
|
|
|
881b8e |
-.* <_start>:
|
|
|
881b8e |
+.* <._start>:
|
|
|
881b8e |
.* (e8 62 80 10|10 80 62 e8) ld r3,-32752\(r2\)
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
.* (7c 63 6a 14|14 6a 63 7c) add r3,r3,r13
|
|
|
881b8e |
@@ -67,22 +67,23 @@ Disassembly of section \.text:
|
|
|
881b8e |
.* (e9 4d 90 2a|2a 90 4d e9) lwa r10,-28632\(r13\)
|
|
|
881b8e |
.* (3d 2d 00 00|00 00 2d 3d) addis r9,r13,0
|
|
|
881b8e |
.* (a9 49 90 30|30 90 49 a9) lha r10,-28624\(r9\)
|
|
|
881b8e |
-.* (00 00 00 00|00 02 01 00) .*
|
|
|
881b8e |
-.* (00 01 02 00|00 00 00 00) .*
|
|
|
881b8e |
+.* (00 00 00 00|18 02 01 00) .*
|
|
|
881b8e |
+.* (00 01 02 18|00 00 00 00) .*
|
|
|
881b8e |
.* <__glink_PLTresolve>:
|
|
|
881b8e |
.* (7d 88 02 a6|a6 02 88 7d) mflr r12
|
|
|
881b8e |
.* (42 9f 00 05|05 00 9f 42) bcl 20,4\*cr7\+so,.*
|
|
|
881b8e |
.* (7d 68 02 a6|a6 02 68 7d) mflr r11
|
|
|
881b8e |
.* (e8 4b ff f0|f0 ff 4b e8) ld r2,-16\(r11\)
|
|
|
881b8e |
.* (7d 88 03 a6|a6 03 88 7d) mtlr r12
|
|
|
881b8e |
-.* (7d 82 5a 14|14 5a 82 7d) add r12,r2,r11
|
|
|
881b8e |
-.* (e9 6c 00 00|00 00 6c e9) ld r11,0\(r12\)
|
|
|
881b8e |
-.* (e8 4c 00 08|08 00 4c e8) ld r2,8\(r12\)
|
|
|
881b8e |
-.* (7d 69 03 a6|a6 03 69 7d) mtctr r11
|
|
|
881b8e |
-.* (e9 6c 00 10|10 00 6c e9) ld r11,16\(r12\)
|
|
|
881b8e |
+.* (7d 62 5a 14|14 5a 62 7d) add r11,r2,r11
|
|
|
881b8e |
+.* (e9 8b 00 00|00 00 8b e9) ld r12,0\(r11\)
|
|
|
881b8e |
+.* (e8 4b 00 08|08 00 4b e8) ld r2,8\(r11\)
|
|
|
881b8e |
+.* (7d 89 03 a6|a6 03 89 7d) mtctr r12
|
|
|
881b8e |
+.* (e9 6b 00 10|10 00 6b e9) ld r11,16\(r11\)
|
|
|
881b8e |
.* (4e 80 04 20|20 04 80 4e) bctr
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
+.* <__tls_get_addr_opt@plt>:
|
|
|
881b8e |
.* (38 00 00 00|00 00 00 38) li r0,0
|
|
|
881b8e |
.* (4b ff ff c4|c4 ff ff 4b) b .*
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tlsexe.g b/ld/testsuite/ld-powerpc/tlsexe.g
|
|
|
881b8e |
index 3420d20..fb8dbb3 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tlsexe.g
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tlsexe.g
|
|
|
881b8e |
@@ -7,6 +7,6 @@
|
|
|
881b8e |
.*
|
|
|
881b8e |
|
|
|
881b8e |
Contents of section \.got:
|
|
|
881b8e |
-.* (00000000|20860110) (10018620|00000000) (ffffffff|1880ffff) (ffff8018|ffffffff) .*
|
|
|
881b8e |
+.* (00000000|38860110) (10018638|00000000) (ffffffff|1880ffff) (ffff8018|ffffffff) .*
|
|
|
881b8e |
.* 00000000 00000000 00000000 00000000 .*
|
|
|
881b8e |
.* 00000000 00000000 00000000 00000000 .*
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tlsexe.r b/ld/testsuite/ld-powerpc/tlsexe.r
|
|
|
881b8e |
index 8d6ff30..72ef3f4 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tlsexe.r
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tlsexe.r
|
|
|
881b8e |
@@ -20,6 +20,7 @@ Section Headers:
|
|
|
881b8e |
+\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
|
|
|
881b8e |
+\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
|
|
|
881b8e |
+\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+160 10 +WA +4 +0 +8
|
|
|
881b8e |
+ +\[[ 0-9]+\] \.opd .*
|
|
|
881b8e |
+\[[ 0-9]+\] \.got +PROGBITS .* 0+30 08 +WA +0 +0 +8
|
|
|
881b8e |
+\[[ 0-9]+\] \.plt +.*
|
|
|
881b8e |
+\[[ 0-9]+\] \.shstrtab +.*
|
|
|
881b8e |
@@ -46,7 +47,7 @@ Program Headers:
|
|
|
881b8e |
+0+ +
|
|
|
881b8e |
+01 +\.interp
|
|
|
881b8e |
+02 +\.interp \.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text
|
|
|
881b8e |
- +03 +\.tdata \.dynamic \.got \.plt
|
|
|
881b8e |
+ +03 +\.tdata \.dynamic \.opd \.got \.plt
|
|
|
881b8e |
+04 +\.dynamic
|
|
|
881b8e |
+05 +\.tdata \.tbss
|
|
|
881b8e |
|
|
|
881b8e |
@@ -66,10 +67,10 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +UND gd
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +UND ld
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +9 ld2
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +13 __bss_start
|
|
|
881b8e |
.* FUNC +GLOBAL +DEFAULT +UND __tls_get_addr_opt
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +11 _edata
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +12 _end
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +12 _edata
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +13 _end
|
|
|
881b8e |
|
|
|
881b8e |
Symbol table '\.symtab' contains [0-9]+ entries:
|
|
|
881b8e |
+Num: +Value +Size +Type +Bind +Vis +Ndx +Name
|
|
|
881b8e |
@@ -86,6 +87,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
|
|
|
881b8e |
.* SECTION +LOCAL +DEFAULT +10
|
|
|
881b8e |
.* SECTION +LOCAL +DEFAULT +11
|
|
|
881b8e |
.* SECTION +LOCAL +DEFAULT +12
|
|
|
881b8e |
+.* SECTION +LOCAL +DEFAULT +13
|
|
|
881b8e |
.* FILE +LOCAL +DEFAULT +ABS .*
|
|
|
881b8e |
.* TLS +LOCAL +DEFAULT +8 gd4
|
|
|
881b8e |
.* TLS +LOCAL +DEFAULT +8 ld4
|
|
|
881b8e |
@@ -104,12 +106,12 @@ Symbol table '\.symtab' contains [0-9]+ entries:
|
|
|
881b8e |
.* GLOBAL +DEFAULT +9 ld0
|
|
|
881b8e |
.* GLOBAL +DEFAULT +9 le1
|
|
|
881b8e |
.* GLOBAL +DEFAULT +UND ld
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +7 _start
|
|
|
881b8e |
+.* FUNC +GLOBAL +DEFAULT +11 _start
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +9 ld2
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +9 ld1
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +13 __bss_start
|
|
|
881b8e |
.* FUNC +GLOBAL +DEFAULT +UND __tls_get_addr_opt
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +11 _edata
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +12 _end
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +12 _edata
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +13 _end
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +9 gd0
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +9 ie0
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tlsexetoc.d b/ld/testsuite/ld-powerpc/tlsexetoc.d
|
|
|
881b8e |
index fc20992..ee0f3b2 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tlsexetoc.d
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tlsexetoc.d
|
|
|
881b8e |
@@ -19,8 +19,8 @@ Disassembly of section \.text:
|
|
|
881b8e |
.* (7d 68 02 a6|a6 02 68 7d) mflr r11
|
|
|
881b8e |
.* (f9 61 00 20|20 00 61 f9) std r11,32\(r1\)
|
|
|
881b8e |
.* (f8 41 00 28|28 00 41 f8) std r2,40\(r1\)
|
|
|
881b8e |
-.* (e9 62 80 70|70 80 62 e9) ld r11,-32656\(r2\)
|
|
|
881b8e |
-.* (7d 69 03 a6|a6 03 69 7d) mtctr r11
|
|
|
881b8e |
+.* (e9 82 80 70|70 80 82 e9) ld r12,-32656\(r2\)
|
|
|
881b8e |
+.* (7d 89 03 a6|a6 03 89 7d) mtctr r12
|
|
|
881b8e |
.* (e8 42 80 78|78 80 42 e8) ld r2,-32648\(r2\)
|
|
|
881b8e |
.* (4e 80 04 21|21 04 80 4e) bctrl
|
|
|
881b8e |
.* (e9 61 00 20|20 00 61 e9) ld r11,32\(r1\)
|
|
|
881b8e |
@@ -28,7 +28,7 @@ Disassembly of section \.text:
|
|
|
881b8e |
.* (7d 68 03 a6|a6 03 68 7d) mtlr r11
|
|
|
881b8e |
.* (4e 80 00 20|20 00 80 4e) blr
|
|
|
881b8e |
|
|
|
881b8e |
-.* <_start>:
|
|
|
881b8e |
+.* <\._start>:
|
|
|
881b8e |
.* (38 62 80 08|08 80 62 38) addi r3,r2,-32760
|
|
|
881b8e |
.* (4b ff ff b5|b5 ff ff 4b) bl .*
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
@@ -51,22 +51,23 @@ Disassembly of section \.text:
|
|
|
881b8e |
.* (89 4d 90 60|60 90 4d 89) lbz r10,-28576\(r13\)
|
|
|
881b8e |
.* (3d 2d 00 00|00 00 2d 3d) addis r9,r13,0
|
|
|
881b8e |
.* (99 49 90 68|68 90 49 99) stb r10,-28568\(r9\)
|
|
|
881b8e |
-.* (00 00 00 00|28 02 01 00) .*
|
|
|
881b8e |
-.* (00 01 02 28|00 00 00 00) .*
|
|
|
881b8e |
+.* (00 00 00 00|40 02 01 00) .*
|
|
|
881b8e |
+.* (00 01 02 40|00 00 00 00) .*
|
|
|
881b8e |
.* <__glink_PLTresolve>:
|
|
|
881b8e |
.* (7d 88 02 a6|a6 02 88 7d) mflr r12
|
|
|
881b8e |
.* (42 9f 00 05|05 00 9f 42) bcl 20,4\*cr7\+so,.*
|
|
|
881b8e |
.* (7d 68 02 a6|a6 02 68 7d) mflr r11
|
|
|
881b8e |
.* (e8 4b ff f0|f0 ff 4b e8) ld r2,-16\(r11\)
|
|
|
881b8e |
.* (7d 88 03 a6|a6 03 88 7d) mtlr r12
|
|
|
881b8e |
-.* (7d 82 5a 14|14 5a 82 7d) add r12,r2,r11
|
|
|
881b8e |
-.* (e9 6c 00 00|00 00 6c e9) ld r11,0\(r12\)
|
|
|
881b8e |
-.* (e8 4c 00 08|08 00 4c e8) ld r2,8\(r12\)
|
|
|
881b8e |
-.* (7d 69 03 a6|a6 03 69 7d) mtctr r11
|
|
|
881b8e |
-.* (e9 6c 00 10|10 00 6c e9) ld r11,16\(r12\)
|
|
|
881b8e |
+.* (7d 62 5a 14|14 5a 62 7d) add r11,r2,r11
|
|
|
881b8e |
+.* (e9 8b 00 00|00 00 8b e9) ld r12,0\(r11\)
|
|
|
881b8e |
+.* (e8 4b 00 08|08 00 4b e8) ld r2,8\(r11\)
|
|
|
881b8e |
+.* (7d 89 03 a6|a6 03 89 7d) mtctr r12
|
|
|
881b8e |
+.* (e9 6b 00 10|10 00 6b e9) ld r11,16\(r11\)
|
|
|
881b8e |
.* (4e 80 04 20|20 04 80 4e) bctr
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
+.* <__tls_get_addr_opt@plt>:
|
|
|
881b8e |
.* (38 00 00 00|00 00 00 38) li r0,0
|
|
|
881b8e |
.* (4b ff ff c4|c4 ff ff 4b) b .*
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tlsexetoc.g b/ld/testsuite/ld-powerpc/tlsexetoc.g
|
|
|
881b8e |
index e219f0e..dc563ad 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tlsexetoc.g
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tlsexetoc.g
|
|
|
881b8e |
@@ -7,7 +7,7 @@
|
|
|
881b8e |
.*: +file format elf64-powerpc
|
|
|
881b8e |
|
|
|
881b8e |
Contents of section \.got:
|
|
|
881b8e |
-.* (00000000|c0850110) (100185c0|00000000) 00000000 00000000 .*
|
|
|
881b8e |
+.* (00000000|d8850110) (100185d8|00000000) 00000000 00000000 .*
|
|
|
881b8e |
.* 00000000 00000000 00000000 00000000 .*
|
|
|
881b8e |
.* 00000000 00000000 (00000000|01000000) (00000001|00000000) .*
|
|
|
881b8e |
.* 00000000 00000000 (00000000|01000000) (00000001|00000000) .*
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tlsexetoc.r b/ld/testsuite/ld-powerpc/tlsexetoc.r
|
|
|
881b8e |
index 71d6c9e..e6f606b 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tlsexetoc.r
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tlsexetoc.r
|
|
|
881b8e |
@@ -20,6 +20,7 @@ Section Headers:
|
|
|
881b8e |
+\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
|
|
|
881b8e |
+\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
|
|
|
881b8e |
+\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+160 10 +WA +4 +0 +8
|
|
|
881b8e |
+ +\[[ 0-9]+\] \.opd .*
|
|
|
881b8e |
+\[[ 0-9]+\] \.got +PROGBITS .* 0+58 08 +WA +0 +0 +8
|
|
|
881b8e |
+\[[ 0-9]+\] \.plt +.*
|
|
|
881b8e |
+\[[ 0-9]+\] \.shstrtab +.*
|
|
|
881b8e |
@@ -46,7 +47,7 @@ Program Headers:
|
|
|
881b8e |
+0+ +
|
|
|
881b8e |
+01 +\.interp
|
|
|
881b8e |
+02 +\.interp \.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text
|
|
|
881b8e |
- +03 +\.tdata \.dynamic \.got \.plt
|
|
|
881b8e |
+ +03 +\.tdata \.dynamic \.opd \.got \.plt
|
|
|
881b8e |
+04 +\.dynamic
|
|
|
881b8e |
+05 +\.tdata \.tbss
|
|
|
881b8e |
|
|
|
881b8e |
@@ -65,10 +66,10 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
|
|
|
881b8e |
.* NOTYPE +LOCAL +DEFAULT +UND
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +UND gd
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +UND ld
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +13 __bss_start
|
|
|
881b8e |
.* FUNC +GLOBAL +DEFAULT +UND __tls_get_addr_opt
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +11 _edata
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +12 _end
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +12 _edata
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +13 _end
|
|
|
881b8e |
|
|
|
881b8e |
Symbol table '\.symtab' contains [0-9]+ entries:
|
|
|
881b8e |
+Num: +Value +Size +Type +Bind +Vis +Ndx +Name
|
|
|
881b8e |
@@ -85,6 +86,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
|
|
|
881b8e |
.* SECTION +LOCAL +DEFAULT +10
|
|
|
881b8e |
.* SECTION +LOCAL +DEFAULT +11
|
|
|
881b8e |
.* SECTION +LOCAL +DEFAULT +12
|
|
|
881b8e |
+.* SECTION +LOCAL +DEFAULT +13
|
|
|
881b8e |
.* FILE +LOCAL +DEFAULT +ABS .*
|
|
|
881b8e |
.* TLS +LOCAL +DEFAULT +8 gd4
|
|
|
881b8e |
.* TLS +LOCAL +DEFAULT +8 ld4
|
|
|
881b8e |
@@ -93,7 +95,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
|
|
|
881b8e |
.* TLS +LOCAL +DEFAULT +8 ie4
|
|
|
881b8e |
.* TLS +LOCAL +DEFAULT +8 le4
|
|
|
881b8e |
.* TLS +LOCAL +DEFAULT +8 le5
|
|
|
881b8e |
-.* NOTYPE +LOCAL +DEFAULT +11 \.Lie0
|
|
|
881b8e |
+.* NOTYPE +LOCAL +DEFAULT +12 \.Lie0
|
|
|
881b8e |
.* (FUNC|NOTYPE) +LOCAL +DEFAULT +UND \.__tls_get_addr(|_opt)
|
|
|
881b8e |
.* FILE +LOCAL +DEFAULT +ABS .*
|
|
|
881b8e |
.* NOTYPE +LOCAL +DEFAULT +7 00000010\.plt_call\.__tls_get_addr(|_opt)
|
|
|
881b8e |
@@ -104,12 +106,12 @@ Symbol table '\.symtab' contains [0-9]+ entries:
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +9 ld0
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +9 le1
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +UND ld
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +7 _start
|
|
|
881b8e |
+.* FUNC +GLOBAL +DEFAULT +11 _start
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +9 ld2
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +9 ld1
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +13 __bss_start
|
|
|
881b8e |
.* FUNC +GLOBAL +DEFAULT +UND __tls_get_addr_opt
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +11 _edata
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +12 _end
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +12 _edata
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +13 _end
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +9 gd0
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +9 ie0
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tlsso.d b/ld/testsuite/ld-powerpc/tlsso.d
|
|
|
881b8e |
index 00b00a0..e64184d 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tlsso.d
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tlsso.d
|
|
|
881b8e |
@@ -10,14 +10,14 @@ Disassembly of section \.text:
|
|
|
881b8e |
|
|
|
881b8e |
.* <00000010\.plt_call\.__tls_get_addr(|_opt)>:
|
|
|
881b8e |
.* (f8 41 00 28|28 00 41 f8) std r2,40\(r1\)
|
|
|
881b8e |
-.* (e9 62 80 78|78 80 62 e9) ld r11,-32648\(r2\)
|
|
|
881b8e |
-.* (7d 69 03 a6|a6 03 69 7d) mtctr r11
|
|
|
881b8e |
+.* (e9 82 80 78|78 80 82 e9) ld r12,-32648\(r2\)
|
|
|
881b8e |
+.* (7d 89 03 a6|a6 03 89 7d) mtctr r12
|
|
|
881b8e |
.* (e8 42 80 80|80 80 42 e8) ld r2,-32640\(r2\)
|
|
|
881b8e |
.* (28 22 00 00|00 00 22 28) cmpldi r2,0
|
|
|
881b8e |
.* (4c e2 04 20|20 04 e2 4c) bnectr\+
|
|
|
881b8e |
-.* (48 00 00 ..|.. 00 00 48) b .* <__glink_PLTresolve\+0x38>
|
|
|
881b8e |
+.* (48 00 00 ..|.. 00 00 48) b .* <__tls_get_addr@plt>
|
|
|
881b8e |
|
|
|
881b8e |
-.* <_start>:
|
|
|
881b8e |
+.* <\._start>:
|
|
|
881b8e |
.* (38 62 80 20|20 80 62 38) addi r3,r2,-32736
|
|
|
881b8e |
.* (4b ff ff ..|.. ff ff 4b) bl .*plt_call.__tls_get_addr.*
|
|
|
881b8e |
.* (e8 41 00 28|28 00 41 e8) ld r2,40\(r1\)
|
|
|
881b8e |
@@ -57,22 +57,23 @@ Disassembly of section \.text:
|
|
|
881b8e |
.* (3d 2d 00 00|00 00 2d 3d) addis r9,r13,0
|
|
|
881b8e |
.* (a9 49 00 00|00 00 49 a9) lha r10,0\(r9\)
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
-.* (00 00 00 00|20 02 01 00) .*
|
|
|
881b8e |
-.* (00 01 02 20|00 00 00 00) .*
|
|
|
881b8e |
+.* (00 00 00 00|38 02 01 00) .*
|
|
|
881b8e |
+.* (00 01 02 38|00 00 00 00) .*
|
|
|
881b8e |
.* <__glink_PLTresolve>:
|
|
|
881b8e |
.* (7d 88 02 a6|a6 02 88 7d) mflr r12
|
|
|
881b8e |
.* (42 9f 00 05|05 00 9f 42) bcl 20,4\*cr7\+so,.*
|
|
|
881b8e |
.* (7d 68 02 a6|a6 02 68 7d) mflr r11
|
|
|
881b8e |
.* (e8 4b ff f0|f0 ff 4b e8) ld r2,-16\(r11\)
|
|
|
881b8e |
.* (7d 88 03 a6|a6 03 88 7d) mtlr r12
|
|
|
881b8e |
-.* (7d 82 5a 14|14 5a 82 7d) add r12,r2,r11
|
|
|
881b8e |
-.* (e9 6c 00 00|00 00 6c e9) ld r11,0\(r12\)
|
|
|
881b8e |
-.* (e8 4c 00 08|08 00 4c e8) ld r2,8\(r12\)
|
|
|
881b8e |
-.* (7d 69 03 a6|a6 03 69 7d) mtctr r11
|
|
|
881b8e |
-.* (e9 6c 00 10|10 00 6c e9) ld r11,16\(r12\)
|
|
|
881b8e |
+.* (7d 62 5a 14|14 5a 62 7d) add r11,r2,r11
|
|
|
881b8e |
+.* (e9 8b 00 00|00 00 8b e9) ld r12,0\(r11\)
|
|
|
881b8e |
+.* (e8 4b 00 08|08 00 4b e8) ld r2,8\(r11\)
|
|
|
881b8e |
+.* (7d 89 03 a6|a6 03 89 7d) mtctr r12
|
|
|
881b8e |
+.* (e9 6b 00 10|10 00 6b e9) ld r11,16\(r11\)
|
|
|
881b8e |
.* (4e 80 04 20|20 04 80 4e) bctr
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
+.* <__tls_get_addr@plt>:
|
|
|
881b8e |
.* (38 00 00 00|00 00 00 38) li r0,0
|
|
|
881b8e |
.* (4b ff ff c4|c4 ff ff 4b) b .*
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tlsso.g b/ld/testsuite/ld-powerpc/tlsso.g
|
|
|
881b8e |
index 8536803..8fd3ce0 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tlsso.g
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tlsso.g
|
|
|
881b8e |
@@ -7,7 +7,7 @@
|
|
|
881b8e |
.*: +file format elf64-powerpc
|
|
|
881b8e |
|
|
|
881b8e |
Contents of section \.got:
|
|
|
881b8e |
- 10788 (00000000|88870100) (00018788|00000000) 00000000 00000000 .*
|
|
|
881b8e |
+ 107e0 (00000000|e0870100) (000187e0|00000000) 00000000 00000000 .*
|
|
|
881b8e |
.* 00000000 00000000 00000000 00000000 .*
|
|
|
881b8e |
.* 00000000 00000000 00000000 00000000 .*
|
|
|
881b8e |
.* 00000000 00000000 00000000 00000000 .*
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tlsso.r b/ld/testsuite/ld-powerpc/tlsso.r
|
|
|
881b8e |
index fab50e0..6464be0 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tlsso.r
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tlsso.r
|
|
|
881b8e |
@@ -18,6 +18,7 @@ Section Headers:
|
|
|
881b8e |
+\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
|
|
|
881b8e |
+\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
|
|
|
881b8e |
+\[[ 0-9]+\] \.dynamic .*
|
|
|
881b8e |
+ +\[[ 0-9]+\] \.opd .*
|
|
|
881b8e |
+\[[ 0-9]+\] \.got .*
|
|
|
881b8e |
+\[[ 0-9]+\] \.plt .*
|
|
|
881b8e |
+\[[ 0-9]+\] \.shstrtab .*
|
|
|
881b8e |
@@ -39,12 +40,14 @@ Program Headers:
|
|
|
881b8e |
Section to Segment mapping:
|
|
|
881b8e |
+Segment Sections\.\.\.
|
|
|
881b8e |
+0+ +\.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text
|
|
|
881b8e |
- +01 +\.tdata \.dynamic .got \.plt
|
|
|
881b8e |
+ +01 +\.tdata \.dynamic \.opd \.got \.plt
|
|
|
881b8e |
+02 +\.dynamic
|
|
|
881b8e |
+03 +\.tdata \.tbss
|
|
|
881b8e |
|
|
|
881b8e |
-Relocation section '\.rela\.dyn' at offset .* contains 16 entries:
|
|
|
881b8e |
+Relocation section '\.rela\.dyn' at offset .* contains 18 entries:
|
|
|
881b8e |
+Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
|
|
|
881b8e |
+[0-9a-f ]+R_PPC64_RELATIVE +55c
|
|
|
881b8e |
+[0-9a-f ]+R_PPC64_RELATIVE +187e0
|
|
|
881b8e |
[0-9a-f ]+R_PPC64_TPREL16 +0+60 le0 \+ 0
|
|
|
881b8e |
[0-9a-f ]+R_PPC64_TPREL16_HA +0+68 le1 \+ 0
|
|
|
881b8e |
[0-9a-f ]+R_PPC64_TPREL16_LO +0+68 le1 \+ 0
|
|
|
881b8e |
@@ -77,12 +80,12 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ld0
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 le1
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +UND ld
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +6 _start
|
|
|
881b8e |
+.* FUNC +GLOBAL +DEFAULT +10 _start
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ld2
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ld1
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +11 __bss_start
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +10 _edata
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +11 _end
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +11 _edata
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +12 _end
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 gd0
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ie0
|
|
|
881b8e |
|
|
|
881b8e |
@@ -100,6 +103,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
|
|
|
881b8e |
.* SECTION +LOCAL +DEFAULT +9
|
|
|
881b8e |
.* SECTION +LOCAL +DEFAULT +10
|
|
|
881b8e |
.* SECTION +LOCAL +DEFAULT +11
|
|
|
881b8e |
+.* SECTION +LOCAL +DEFAULT +12
|
|
|
881b8e |
.* FILE +LOCAL +DEFAULT +ABS .*
|
|
|
881b8e |
.* TLS +LOCAL +DEFAULT +7 gd4
|
|
|
881b8e |
.* TLS +LOCAL +DEFAULT +7 ld4
|
|
|
881b8e |
@@ -119,11 +123,11 @@ Symbol table '\.symtab' contains [0-9]+ entries:
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ld0
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 le1
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +UND ld
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +6 _start
|
|
|
881b8e |
+.* FUNC +GLOBAL +DEFAULT +10 _start
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ld2
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ld1
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +11 __bss_start
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +10 _edata
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +11 _end
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +11 _edata
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +12 _end
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 gd0
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ie0
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tlstoc.d b/ld/testsuite/ld-powerpc/tlstoc.d
|
|
|
881b8e |
index faea1c4..05f61af 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tlstoc.d
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tlstoc.d
|
|
|
881b8e |
@@ -12,7 +12,7 @@ Disassembly of section \.text:
|
|
|
881b8e |
.* <\.__tls_get_addr>:
|
|
|
881b8e |
.* (4e 80 00 20|20 00 80 4e) blr
|
|
|
881b8e |
|
|
|
881b8e |
-.* <_start>:
|
|
|
881b8e |
+.* <\._start>:
|
|
|
881b8e |
.* (3c 6d 00 00|00 00 6d 3c) addis r3,r13,0
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
.* (38 63 90 40|40 90 63 38) addi r3,r3,-28608
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tlstoc.g b/ld/testsuite/ld-powerpc/tlstoc.g
|
|
|
881b8e |
index 9ca4302..e3fe1d3 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tlstoc.g
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tlstoc.g
|
|
|
881b8e |
@@ -8,8 +8,8 @@
|
|
|
881b8e |
.*
|
|
|
881b8e |
|
|
|
881b8e |
Contents of section \.got:
|
|
|
881b8e |
- 100101a0 (00000000|01000000) (00000001|00000000) 00000000 00000000 .*
|
|
|
881b8e |
- 100101b0 (00000000|01000000) (00000001|00000000) 00000000 00000000 .*
|
|
|
881b8e |
- 100101c0 (00000000|01000000) (00000001|00000000) 00000000 00000000 .*
|
|
|
881b8e |
- 100101d0 (00000000|01000000) (00000001|00000000) 00000000 00000000 .*
|
|
|
881b8e |
- 100101e0 (ffffffff|6080ffff) (ffff8060|ffffffff) 00000000 00000000 .*
|
|
|
881b8e |
+ 100101b8 (00000000|01000000) (00000001|00000000) 00000000 00000000 .*
|
|
|
881b8e |
+ 100101c8 (00000000|01000000) (00000001|00000000) 00000000 00000000 .*
|
|
|
881b8e |
+ 100101d8 (00000000|01000000) (00000001|00000000) 00000000 00000000 .*
|
|
|
881b8e |
+ 100101e8 (00000000|01000000) (00000001|00000000) 00000000 00000000 .*
|
|
|
881b8e |
+ 100101f8 (ffffffff|6080ffff) (ffff8060|ffffffff) 00000000 00000000 .*
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tlstoc.s b/ld/testsuite/ld-powerpc/tlstoc.s
|
|
|
881b8e |
index 5008d89..f5dbfdd 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tlstoc.s
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tlstoc.s
|
|
|
881b8e |
@@ -19,8 +19,13 @@ ie4: .quad 0x56789abcdef01234
|
|
|
881b8e |
le4: .quad 0x6789abcdef012345
|
|
|
881b8e |
le5: .quad 0x789abcdef0123456
|
|
|
881b8e |
|
|
|
881b8e |
- .text
|
|
|
881b8e |
+ .section ".opd","aw",@progbits
|
|
|
881b8e |
+ .p2align 3
|
|
|
881b8e |
_start:
|
|
|
881b8e |
+ .quad .L_start,.TOC.@tocbase,0
|
|
|
881b8e |
+
|
|
|
881b8e |
+ .text
|
|
|
881b8e |
+.L_start:
|
|
|
881b8e |
#extern syms
|
|
|
881b8e |
#GD
|
|
|
881b8e |
addi 3,2,.Lgd@toc
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tlstocso.d b/ld/testsuite/ld-powerpc/tlstocso.d
|
|
|
881b8e |
index a0cd08f..fa3b77a 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tlstocso.d
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tlstocso.d
|
|
|
881b8e |
@@ -10,14 +10,14 @@ Disassembly of section \.text:
|
|
|
881b8e |
|
|
|
881b8e |
.* <00000010\.plt_call\.__tls_get_addr(|_opt)>:
|
|
|
881b8e |
.* (f8 41 00 28|28 00 41 f8) std r2,40\(r1\)
|
|
|
881b8e |
-.* (e9 62 80 70|70 80 62 e9) ld r11,-32656\(r2\)
|
|
|
881b8e |
-.* (7d 69 03 a6|a6 03 69 7d) mtctr r11
|
|
|
881b8e |
+.* (e9 82 80 70|70 80 82 e9) ld r12,-32656\(r2\)
|
|
|
881b8e |
+.* (7d 89 03 a6|a6 03 89 7d) mtctr r12
|
|
|
881b8e |
.* (e8 42 80 78|78 80 42 e8) ld r2,-32648\(r2\)
|
|
|
881b8e |
.* (28 22 00 00|00 00 22 28) cmpldi r2,0
|
|
|
881b8e |
.* (4c e2 04 20|20 04 e2 4c) bnectr\+
|
|
|
881b8e |
-.* (48 00 00 ..|.. 00 00 48) b .* <__glink_PLTresolve\+0x38>
|
|
|
881b8e |
+.* (48 00 00 ..|.. 00 00 48) b .* <__tls_get_addr@plt>
|
|
|
881b8e |
|
|
|
881b8e |
-.* <_start>:
|
|
|
881b8e |
+.* <\._start>:
|
|
|
881b8e |
.* (38 62 80 08|08 80 62 38) addi r3,r2,-32760
|
|
|
881b8e |
.* (4b ff ff ..|.. ff ff 4b) bl .*plt_call.__tls_get_addr.*
|
|
|
881b8e |
.* (e8 41 00 28|28 00 41 e8) ld r2,40\(r1\)
|
|
|
881b8e |
@@ -41,22 +41,23 @@ Disassembly of section \.text:
|
|
|
881b8e |
.* (3d 2d 00 00|00 00 2d 3d) addis r9,r13,0
|
|
|
881b8e |
.* (99 49 00 00|00 00 49 99) stb r10,0\(r9\)
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
-.* (00 00 00 00|18 02 01 00) .*
|
|
|
881b8e |
-.* (00 01 02 18|00 00 00 00) .*
|
|
|
881b8e |
+.* (00 00 00 00|30 02 01 00) .*
|
|
|
881b8e |
+.* (00 01 02 30|00 00 00 00) .*
|
|
|
881b8e |
.* <__glink_PLTresolve>:
|
|
|
881b8e |
.* (7d 88 02 a6|a6 02 88 7d) mflr r12
|
|
|
881b8e |
.* (42 9f 00 05|05 00 9f 42) bcl 20,4\*cr7\+so,.*
|
|
|
881b8e |
.* (7d 68 02 a6|a6 02 68 7d) mflr r11
|
|
|
881b8e |
.* (e8 4b ff f0|f0 ff 4b e8) ld r2,-16\(r11\)
|
|
|
881b8e |
.* (7d 88 03 a6|a6 03 88 7d) mtlr r12
|
|
|
881b8e |
-.* (7d 82 5a 14|14 5a 82 7d) add r12,r2,r11
|
|
|
881b8e |
-.* (e9 6c 00 00|00 00 6c e9) ld r11,0\(r12\)
|
|
|
881b8e |
-.* (e8 4c 00 08|08 00 4c e8) ld r2,8\(r12\)
|
|
|
881b8e |
-.* (7d 69 03 a6|a6 03 69 7d) mtctr r11
|
|
|
881b8e |
-.* (e9 6c 00 10|10 00 6c e9) ld r11,16\(r12\)
|
|
|
881b8e |
+.* (7d 62 5a 14|14 5a 62 7d) add r11,r2,r11
|
|
|
881b8e |
+.* (e9 8b 00 00|00 00 8b e9) ld r12,0\(r11\)
|
|
|
881b8e |
+.* (e8 4b 00 08|08 00 4b e8) ld r2,8\(r11\)
|
|
|
881b8e |
+.* (7d 89 03 a6|a6 03 89 7d) mtctr r12
|
|
|
881b8e |
+.* (e9 6b 00 10|10 00 6b e9) ld r11,16\(r11\)
|
|
|
881b8e |
.* (4e 80 04 20|20 04 80 4e) bctr
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
.* (60 00 00 00|00 00 00 60) nop
|
|
|
881b8e |
+.* <__tls_get_addr@plt>:
|
|
|
881b8e |
.* (38 00 00 00|00 00 00 38) li r0,0
|
|
|
881b8e |
.* (4b ff ff c4|c4 ff ff 4b) b .*
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-powerpc/tlstocso.r b/ld/testsuite/ld-powerpc/tlstocso.r
|
|
|
881b8e |
index 1ec8b63..f397915 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-powerpc/tlstocso.r
|
|
|
881b8e |
+++ b/ld/testsuite/ld-powerpc/tlstocso.r
|
|
|
881b8e |
@@ -18,6 +18,7 @@ Section Headers:
|
|
|
881b8e |
+\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
|
|
|
881b8e |
+\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
|
|
|
881b8e |
+\[[ 0-9]+\] \.dynamic .*
|
|
|
881b8e |
+ +\[[ 0-9]+\] \.opd .*
|
|
|
881b8e |
+\[[ 0-9]+\] \.got .*
|
|
|
881b8e |
+\[[ 0-9]+\] \.plt .*
|
|
|
881b8e |
+\[[ 0-9]+\] \.shstrtab .*
|
|
|
881b8e |
@@ -39,12 +40,14 @@ Program Headers:
|
|
|
881b8e |
Section to Segment mapping:
|
|
|
881b8e |
+Segment Sections\.\.\.
|
|
|
881b8e |
+0+ +\.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text
|
|
|
881b8e |
- +01 +\.tdata \.dynamic \.got \.plt
|
|
|
881b8e |
+ +01 +\.tdata \.dynamic \.opd \.got \.plt
|
|
|
881b8e |
+02 +\.dynamic
|
|
|
881b8e |
+03 +\.tdata \.tbss
|
|
|
881b8e |
|
|
|
881b8e |
-Relocation section '\.rela\.dyn' at offset .* contains 11 entries:
|
|
|
881b8e |
+Relocation section '\.rela\.dyn' at offset .* contains 13 entries:
|
|
|
881b8e |
+Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
|
|
|
881b8e |
+[0-9a-f ]+R_PPC64_RELATIVE +4dc
|
|
|
881b8e |
+[0-9a-f ]+R_PPC64_RELATIVE +18720
|
|
|
881b8e |
[0-9a-f ]+R_PPC64_TPREL16 +0+60 le0 \+ 0
|
|
|
881b8e |
[0-9a-f ]+R_PPC64_TPREL16_HA +0+68 le1 \+ 0
|
|
|
881b8e |
[0-9a-f ]+R_PPC64_TPREL16_LO +0+68 le1 \+ 0
|
|
|
881b8e |
@@ -72,12 +75,12 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ld0
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 le1
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +UND ld
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +6 _start
|
|
|
881b8e |
+.* FUNC +GLOBAL +DEFAULT +10 _start
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ld2
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ld1
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +11 __bss_start
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +10 _edata
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +11 _end
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +11 _edata
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +12 _end
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 gd0
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ie0
|
|
|
881b8e |
|
|
|
881b8e |
@@ -95,6 +98,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
|
|
|
881b8e |
.* SECTION +LOCAL +DEFAULT +9
|
|
|
881b8e |
.* SECTION +LOCAL +DEFAULT +10
|
|
|
881b8e |
.* SECTION +LOCAL +DEFAULT +11
|
|
|
881b8e |
+.* SECTION +LOCAL +DEFAULT +12
|
|
|
881b8e |
.* FILE +LOCAL +DEFAULT +ABS .*
|
|
|
881b8e |
.* TLS +LOCAL +DEFAULT +7 gd4
|
|
|
881b8e |
.* TLS +LOCAL +DEFAULT +7 ld4
|
|
|
881b8e |
@@ -103,7 +107,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
|
|
|
881b8e |
.* TLS +LOCAL +DEFAULT +7 ie4
|
|
|
881b8e |
.* TLS +LOCAL +DEFAULT +7 le4
|
|
|
881b8e |
.* TLS +LOCAL +DEFAULT +7 le5
|
|
|
881b8e |
-.* NOTYPE +LOCAL +DEFAULT +10 \.Lie0
|
|
|
881b8e |
+.* NOTYPE +LOCAL +DEFAULT +11 \.Lie0
|
|
|
881b8e |
.* NOTYPE +LOCAL +DEFAULT +UND \.__tls_get_addr
|
|
|
881b8e |
.* FILE +LOCAL +DEFAULT +ABS .*
|
|
|
881b8e |
.* OBJECT +LOCAL +DEFAULT +9 _DYNAMIC
|
|
|
881b8e |
@@ -115,11 +119,11 @@ Symbol table '\.symtab' contains [0-9]+ entries:
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ld0
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 le1
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +UND ld
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +6 _start
|
|
|
881b8e |
+.* FUNC +GLOBAL +DEFAULT +10 _start
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ld2
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ld1
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +11 __bss_start
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +10 _edata
|
|
|
881b8e |
-.* NOTYPE +GLOBAL +DEFAULT +11 _end
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +11 _edata
|
|
|
881b8e |
+.* NOTYPE +GLOBAL +DEFAULT +12 _end
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 gd0
|
|
|
881b8e |
.* TLS +GLOBAL +DEFAULT +8 ie0
|
|
|
881b8e |
diff --git a/ld/testsuite/ld-scripts/crossref.exp b/ld/testsuite/ld-scripts/crossref.exp
|
|
|
881b8e |
index 061b5aa..01fdeb4 100644
|
|
|
881b8e |
--- a/ld/testsuite/ld-scripts/crossref.exp
|
|
|
881b8e |
+++ b/ld/testsuite/ld-scripts/crossref.exp
|
|
|
881b8e |
@@ -31,9 +31,11 @@ if { ![is_remote host] && [which $CC] == 0 } {
|
|
|
881b8e |
return
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
+global CFLAGS
|
|
|
881b8e |
+set old_CFLAGS "$CFLAGS"
|
|
|
881b8e |
+
|
|
|
881b8e |
# Xtensa targets currently default to putting literal values in a separate
|
|
|
881b8e |
# section and that requires linker script support, so put literals in text.
|
|
|
881b8e |
-global CFLAGS
|
|
|
881b8e |
if [istarget xtensa*-*-*] {
|
|
|
881b8e |
set CFLAGS "$CFLAGS -mtext-section-literals"
|
|
|
881b8e |
}
|
|
|
881b8e |
@@ -41,7 +43,7 @@ if [istarget xtensa*-*-*] {
|
|
|
881b8e |
# If we have a compiler that doesn't use/reference dot-symbols, then
|
|
|
881b8e |
# calls to functions reference the .opd section function descriptor.
|
|
|
881b8e |
# This makes NOCROSSREFS rather useless on powerpc64.
|
|
|
881b8e |
-if [istarget powerpc64*-*-*] {
|
|
|
881b8e |
+if [istarget powerpc64-*-*] {
|
|
|
881b8e |
set CFLAGS "$CFLAGS -mcall-aixdesc"
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
@@ -61,6 +63,7 @@ if { ![ld_compile $CC "$srcdir/$subdir/cross1.c" tmpdir/cross1.o] \
|
|
|
881b8e |
|| ![ld_compile $CC "$srcdir/$subdir/cross2.c" tmpdir/cross2.o] } {
|
|
|
881b8e |
unresolved $test1
|
|
|
881b8e |
unresolved $test2
|
|
|
881b8e |
+ set CFLAGS "$old_CFLAGS"
|
|
|
881b8e |
return
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
@@ -95,6 +98,7 @@ if [string match "" $exec_output] then {
|
|
|
881b8e |
|
|
|
881b8e |
if { ![ld_compile $CC "$srcdir/$subdir/cross3.c" tmpdir/cross3.o] } {
|
|
|
881b8e |
unresolved $test2
|
|
|
881b8e |
+ set CFLAGS "$old_CFLAGS"
|
|
|
881b8e |
return
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
@@ -118,11 +122,13 @@ if [string match "" $exec_output] then {
|
|
|
881b8e |
|
|
|
881b8e |
if { ![ld_compile $CC "$srcdir/$subdir/cross4.c" tmpdir/cross4.o] } {
|
|
|
881b8e |
unresolved $test3
|
|
|
881b8e |
+ set CFLAGS "$old_CFLAGS"
|
|
|
881b8e |
return
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
if ![ld_relocate $ld tmpdir/cross3-partial.o "tmpdir/cross1.o tmpdir/cross4.o"] {
|
|
|
881b8e |
unresolved $test3
|
|
|
881b8e |
+ set CFLAGS "$old_CFLAGS"
|
|
|
881b8e |
return
|
|
|
881b8e |
}
|
|
|
881b8e |
|
|
|
881b8e |
@@ -138,3 +144,5 @@ if [string match "" $exec_output] then {
|
|
|
881b8e |
verbose -log "$exec_output"
|
|
|
881b8e |
fail $test3
|
|
|
881b8e |
}
|
|
|
881b8e |
+
|
|
|
881b8e |
+set CFLAGS "$old_CFLAGS"
|