aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf64-ppc.c8
-rw-r--r--bfd/elf64-ppc.h3
-rw-r--r--ld/ChangeLog8
-rw-r--r--ld/emulparams/elf64ppc.sh2
-rw-r--r--ld/emultempl/ppc64elf.em38
-rw-r--r--ld/ldlang.c1
-rw-r--r--ld/testsuite/ChangeLog6
-rw-r--r--ld/testsuite/ld-powerpc/powerpc.exp2
-rw-r--r--ld/testsuite/ld-powerpc/tocnovar.d14
-rw-r--r--ld/testsuite/ld-powerpc/tocnovar.s16
-rw-r--r--ld/testsuite/ld-powerpc/tocvar.d14
-rw-r--r--ld/testsuite/ld-powerpc/tocvar.s17
13 files changed, 131 insertions, 4 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 581b312..f5a50fa 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2015-01-28 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.h (struct ppc64_elf_params): Add "object_in_toc".
+ * elf64-ppc.c (ppc64_elf_add_symbol_hook): Assume that global symbols
+ in .toc indicate xlc compiled code that might require a rw .toc.
+
2015-01-28 James Bowman <james.bowman@ftdichip.com>
* Makefile.am: Add FT32 files.
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 8c7c3b7..da37465 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -4836,6 +4836,14 @@ ppc64_elf_add_symbol_hook (bfd *ibfd,
isym->st_shndx = SHN_UNDEF;
}
}
+ else if (*sec != NULL
+ && strcmp ((*sec)->name, ".toc") == 0
+ && ELF_ST_TYPE (isym->st_info) == STT_OBJECT)
+ {
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+ if (htab != NULL)
+ htab->params->object_in_toc = 1;
+ }
if ((STO_PPC64_LOCAL_MASK & isym->st_other) != 0)
{
diff --git a/bfd/elf64-ppc.h b/bfd/elf64-ppc.h
index 8c627a4..19f72b5 100644
--- a/bfd/elf64-ppc.h
+++ b/bfd/elf64-ppc.h
@@ -57,6 +57,9 @@ struct ppc64_elf_params
/* Whether to generate out-of-line register save/restore for gcc -Os code. */
int save_restore_funcs;
+
+ /* Set when a potential variable is detected in .toc. */
+ int object_in_toc;
};
bfd_boolean ppc64_elf_init_stub_bfd
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 4a16b50..9cab995 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,11 @@
+2015-01-28 Alan Modra <amodra@gmail.com>
+
+ * emulparams/elf64ppc.sh (INITIAL_READWRITE_SECTIONS): Define.
+ * emultempl/ppc64elf.em (params): Init new field.
+ (ppc_after_open): New function.
+ (LDEMUL_AFTER_OPEN): Define.
+ * ldlang.c (lang_final): Whitespace fix.
+
2015-01-28 James Bowman <james.bowman@ftdichip.com>
* Makefile.am: Add FT32 files.
diff --git a/ld/emulparams/elf64ppc.sh b/ld/emulparams/elf64ppc.sh
index b805dbe..d6b09bf 100644
--- a/ld/emulparams/elf64ppc.sh
+++ b/ld/emulparams/elf64ppc.sh
@@ -38,6 +38,8 @@ OTHER_RELRO_SECTIONS_2="
.opd ${RELOCATING-0} :${RELOCATING+ ALIGN(8)} { KEEP (*(.opd)) }
.toc1 ${RELOCATING-0} :${RELOCATING+ ALIGN(8)} { *(.toc1) }
.branch_lt ${RELOCATING-0} :${RELOCATING+ ALIGN(8)} { *(.branch_lt) }"
+INITIAL_READWRITE_SECTIONS="
+ .toc ${RELOCATING-0} :${RELOCATING+ ALIGN(8)} { *(.toc) }"
# Put .got before .data
DATA_GOT=" "
# Always make .got read-only after relocation
diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
index a803c5c..5a784fd 100644
--- a/ld/emultempl/ppc64elf.em
+++ b/ld/emultempl/ppc64elf.em
@@ -39,7 +39,7 @@ static struct ppc64_elf_params params = { NULL,
&ppc_layout_sections_again,
1, 0, 0,
${DEFAULT_PLT_STATIC_CHAIN-0}, -1, 0,
- 0, -1, -1};
+ 0, -1, -1, 0};
/* Fake input file for stubs. */
static lang_input_statement_type *stub_file;
@@ -98,6 +98,37 @@ ppc_create_output_section_statements (void)
einfo ("%F%P: can not init BFD: %E\n");
}
+/* Called after opening files but before mapping sections. */
+
+static void
+ppc_after_open (void)
+{
+ if (stub_file != NULL && link_info.relro && params.object_in_toc)
+ {
+ /* We have a .toc section that might be written to at run time.
+ Don't put .toc into the .got output section. */
+ lang_output_section_statement_type *got;
+
+ got = lang_output_section_find (".got");
+ if (got != NULL)
+ {
+ lang_statement_union_type *s;
+ for (s = got->children.head; s != NULL; s = s->header.next)
+ if (s->header.type == lang_wild_statement_enum
+ && s->wild_statement.filename == NULL)
+ {
+ struct wildcard_list **i = &s->wild_statement.section_list;
+ while (*i != NULL)
+ if (strcmp ((*i)->spec.name, ".toc") == 0)
+ *i = (*i)->next;
+ else
+ i = &(*i)->next;
+ }
+ }
+ }
+ gld${EMULATION_NAME}_after_open ();
+}
+
/* Move the input section statement at *U which happens to be on LIST
to be just before *TO. */
@@ -874,8 +905,9 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
# Put these extra ppc64elf routines in ld_${EMULATION_NAME}_emulation
#
+LDEMUL_NEW_VERS_PATTERN=gld${EMULATION_NAME}_new_vers_pattern
+LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_create_output_section_statements
+LDEMUL_AFTER_OPEN=ppc_after_open
LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation
LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
LDEMUL_FINISH=gld${EMULATION_NAME}_finish
-LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_create_output_section_statements
-LDEMUL_NEW_VERS_PATTERN=gld${EMULATION_NAME}_new_vers_pattern
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 5344e5e..3a4257c 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -6295,7 +6295,6 @@ lang_final (void)
new_stmt = new_stat (lang_output_statement, stat_ptr);
new_stmt->name = output_filename;
-
}
/* Reset the current counters in the regions. */
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 4746f14..e249d69 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2015-01-28 Alan Modra <amodra@gmail.com>
+
+ * ld-powerpc/tocvar.d, * ld-powerpc/tocvar.s: New test.
+ * ld-powerpc/tocnovar.d, * ld-powerpc/tocnovar.s: New test.
+ * ld-powerpc/powerpc.exp: Run tocvar and tocnovar.
+
2015-01-28 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
* ld-scripts/memory.t: Define new symbol tred.
diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp
index 11f1e4f..81cc310 100644
--- a/ld/testsuite/ld-powerpc/powerpc.exp
+++ b/ld/testsuite/ld-powerpc/powerpc.exp
@@ -320,3 +320,5 @@ run_dump_test "attr-gnu-12-11"
run_dump_test "attr-gnu-12-21"
run_dump_test "vle-multiseg-6"
+run_dump_test "tocvar"
+run_dump_test "tocnovar"
diff --git a/ld/testsuite/ld-powerpc/tocnovar.d b/ld/testsuite/ld-powerpc/tocnovar.d
new file mode 100644
index 0000000..d1fd258
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/tocnovar.d
@@ -0,0 +1,14 @@
+#source: tocnovar.s
+#as: -a64
+#ld: -melf64ppc -z relro
+#readelf: -l --wide
+#target: powerpc64*-*-*
+
+#...
+ +LOAD .*
+ +LOAD .*
+ +GNU_RELRO .*
+#...
+ +00 +\.text
+ +01 +\.opd \.got
+ +02 +\.opd \.got
diff --git a/ld/testsuite/ld-powerpc/tocnovar.s b/ld/testsuite/ld-powerpc/tocnovar.s
new file mode 100644
index 0000000..8045d14
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/tocnovar.s
@@ -0,0 +1,16 @@
+ .section .opd,"aw",@progbits
+ .global _start
+ .type _start,@function
+_start:
+ .quad .L_start, .TOC.@tocbase, 0
+
+ .text
+.L_start:
+ lwz 3,x@toc(2)
+ b _start
+ .size _start,.-.L_start
+
+ .section .toc,"aw",@progbits
+ .type x,@object
+x: .long 0
+ .size x,.-x
diff --git a/ld/testsuite/ld-powerpc/tocvar.d b/ld/testsuite/ld-powerpc/tocvar.d
new file mode 100644
index 0000000..62bc998
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/tocvar.d
@@ -0,0 +1,14 @@
+#source: tocvar.s
+#as: -a64
+#ld: -melf64ppc -z relro
+#readelf: -l --wide
+#target: powerpc64*-*-*
+
+#...
+ +LOAD .*
+ +LOAD .*
+ +GNU_RELRO .*
+#...
+ +00 +\.text
+ +01 +\.opd \.toc
+ +02 +\.opd
diff --git a/ld/testsuite/ld-powerpc/tocvar.s b/ld/testsuite/ld-powerpc/tocvar.s
new file mode 100644
index 0000000..d4ebbbe
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/tocvar.s
@@ -0,0 +1,17 @@
+ .section .opd,"aw",@progbits
+ .global _start
+ .type _start,@function
+_start:
+ .quad .L_start, .TOC.@tocbase, 0
+
+ .text
+.L_start:
+ lwz 3,x@toc(2)
+ b _start
+ .size _start,.-.L_start
+
+ .section .toc,"aw",@progbits
+ .global x
+ .type x,@object
+x: .long 0
+ .size x,.-x