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.
This commit is contained in:
parent
3f8107ab38
commit
dbd1e97e32
@ -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.
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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.
|
||||
|
@ -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"
|
||||
|
14
ld/testsuite/ld-powerpc/tocnovar.d
Normal file
14
ld/testsuite/ld-powerpc/tocnovar.d
Normal file
@ -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
|
16
ld/testsuite/ld-powerpc/tocnovar.s
Normal file
16
ld/testsuite/ld-powerpc/tocnovar.s
Normal file
@ -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
|
14
ld/testsuite/ld-powerpc/tocvar.d
Normal file
14
ld/testsuite/ld-powerpc/tocvar.d
Normal file
@ -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
|
17
ld/testsuite/ld-powerpc/tocvar.s
Normal file
17
ld/testsuite/ld-powerpc/tocvar.s
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user