aboutsummaryrefslogtreecommitdiff
path: root/ld/emultempl
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-01-27 23:40:05 +1030
committerAlan Modra <amodra@gmail.com>2015-01-28 18:30:54 +1030
commitdbd1e97e32057af2841e5150daa2e2d4cb046a3b (patch)
treead21bab1f655d821724de5eab738bd4016aff80d /ld/emultempl
parent3f8107ab38095bb3db840f9f14a0fd339f55e06e (diff)
downloadbinutils-dbd1e97e32057af2841e5150daa2e2d4cb046a3b.zip
binutils-dbd1e97e32057af2841e5150daa2e2d4cb046a3b.tar.gz
binutils-dbd1e97e32057af2841e5150daa2e2d4cb046a3b.tar.bz2
PowerPC64 changes for xlc
The changes to reorder sections for better relro protection on powerpc64, 3e2b0f31, 23283c1b, and 5ad18f16, run into a problem with xlc. xlc -qdatalocal puts global variables into .toc, which means that .toc must be writable. The simplest way to accomplish this is to edit the linker script to remove .toc sections from .got on detecting xlc object files. bfd/ * 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. ld/ * 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. ld/testsuite/ * 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.
Diffstat (limited to 'ld/emultempl')
-rw-r--r--ld/emultempl/ppc64elf.em38
1 files changed, 35 insertions, 3 deletions
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