diff options
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 8 | ||||
-rw-r--r-- | bfd/elf64-ppc.h | 3 | ||||
-rw-r--r-- | ld/ChangeLog | 8 | ||||
-rw-r--r-- | ld/emulparams/elf64ppc.sh | 2 | ||||
-rw-r--r-- | ld/emultempl/ppc64elf.em | 38 | ||||
-rw-r--r-- | ld/ldlang.c | 1 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/powerpc.exp | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/tocnovar.d | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/tocnovar.s | 16 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/tocvar.d | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/tocvar.s | 17 |
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 |