diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2013-11-14 18:50:48 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2013-11-14 18:50:48 +0000 |
commit | b54214fe22107618e7dd7c6abd3bff9526fcb3e5 (patch) | |
tree | a0a8fa24a9935839e0db8a171f488dec1d6e7783 /libgcc | |
parent | 140f2c812c50fbe104c3a251c530454a2682c891 (diff) | |
download | gcc-b54214fe22107618e7dd7c6abd3bff9526fcb3e5.zip gcc-b54214fe22107618e7dd7c6abd3bff9526fcb3e5.tar.gz gcc-b54214fe22107618e7dd7c6abd3bff9526fcb3e5.tar.bz2 |
rs6000.h (RS6000_SAVE_AREA): Handle ABI_ELFv2.
gcc/ChangeLog:
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
Alan Modra <amodra@gmail.com>
* config/rs6000/rs6000.h (RS6000_SAVE_AREA): Handle ABI_ELFv2.
(RS6000_SAVE_TOC): Remove.
(RS6000_TOC_SAVE_SLOT): New macro.
* config/rs6000/rs6000.c (rs6000_parm_offset): New function.
(rs6000_parm_start): Use it.
(rs6000_function_arg_advance_1): Likewise.
(rs6000_emit_prologue): Use RS6000_TOC_SAVE_SLOT.
(rs6000_emit_epilogue): Likewise.
(rs6000_call_aix): Likewise.
(rs6000_output_function_prologue): Do not save/restore r11
around calling _mcount for ABI_ELFv2.
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
Alan Modra <amodra@gmail.com>
* config/rs6000/rs6000-protos.h (rs6000_reg_parm_stack_space):
Add prototype.
* config/rs6000/rs6000.h (RS6000_REG_SAVE): Remove.
(REG_PARM_STACK_SPACE): Call rs6000_reg_parm_stack_space.
* config/rs6000/rs6000.c (rs6000_parm_needs_stack): New function.
(rs6000_function_parms_need_stack): Likewise.
(rs6000_reg_parm_stack_space): Likewise.
(rs6000_function_arg): Do not replace BLKmode by Pmode when
returning a register argument.
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
Michael Gschwind <mkg@us.ibm.com>
* config/rs6000/rs6000.h (FP_ARG_MAX_RETURN): New macro.
(ALTIVEC_ARG_MAX_RETURN): Likewise.
(FUNCTION_VALUE_REGNO_P): Use them.
* config/rs6000/rs6000.c (TARGET_RETURN_IN_MSB): Define.
(rs6000_return_in_msb): New function.
(rs6000_return_in_memory): Handle ELFv2 homogeneous aggregates.
Handle aggregates of up to 16 bytes for ELFv2.
(rs6000_function_value): Handle ELFv2 homogeneous aggregates.
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
Michael Gschwind <mkg@us.ibm.com>
* config/rs6000/rs6000.h (AGGR_ARG_NUM_REG): Define.
* config/rs6000/rs6000.c (rs6000_aggregate_candidate): New function.
(rs6000_discover_homogeneous_aggregate): Likewise.
(rs6000_function_arg_boundary): Handle homogeneous aggregates.
(rs6000_function_arg_advance_1): Likewise.
(rs6000_function_arg): Likewise.
(rs6000_arg_partial_bytes): Likewise.
(rs6000_psave_function_arg): Handle BLKmode arguments.
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
Michael Gschwind <mkg@us.ibm.com>
* config/rs6000/rs6000.h (AGGR_ARG_NUM_REG): Define.
* config/rs6000/rs6000.c (rs6000_aggregate_candidate): New function.
(rs6000_discover_homogeneous_aggregate): Likewise.
(rs6000_function_arg_boundary): Handle homogeneous aggregates.
(rs6000_function_arg_advance_1): Likewise.
(rs6000_function_arg): Likewise.
(rs6000_arg_partial_bytes): Likewise.
(rs6000_psave_function_arg): Handle BLKmode arguments.
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* config/rs6000/rs6000.c (machine_function): New member
r2_setup_needed.
(rs6000_emit_prologue): Set r2_setup_needed if necessary.
(rs6000_output_mi_thunk): Set r2_setup_needed.
(rs6000_output_function_prologue): Output global entry point
prologue and local entry point marker if needed for ABI_ELFv2.
Output -mprofile-kernel code here.
(output_function_profiler): Do not output -mprofile-kernel
code here; moved to rs6000_output_function_prologue.
(rs6000_file_start): Output ".abiversion 2" for ABI_ELFv2.
(rs6000_emit_move): Do not handle dot symbols for ABI_ELFv2.
(rs6000_output_function_entry): Likewise.
(rs6000_assemble_integer): Likewise.
(rs6000_elf_encode_section_info): Likewise.
(rs6000_elf_declare_function_name): Do not create dot symbols
or .opd section for ABI_ELFv2.
(rs6000_trampoline_size): Update for ABI_ELFv2 trampolines.
(rs6000_trampoline_init): Likewise.
(rs6000_elf_file_end): Call file_end_indicate_exec_stack
for ABI_ELFv2.
(rs6000_call_aix): Handle ELFv2 indirect calls. Do not check
for function descriptors in ABI_ELFv2.
* config/rs6000/rs6000.md ("*call_indirect_aix<mode>"): Support
on ABI_AIX only, not ABI_ELFv2.
("*call_value_indirect_aix<mode>"): Likewise.
("*call_indirect_elfv2<mode>"): New pattern.
("*call_value_indirect_elfv2<mode>"): Likewise.
* config/rs6000/predicates.md ("symbol_ref_operand"): Do not
check for function descriptors in ABI_ELFv2.
("current_file_function_operand"): Likewise.
* config/rs6000/ppc-asm.h [__powerpc64__ && _CALL_ELF == 2]:
(toc): Undefine.
(FUNC_NAME): Define ELFv2 variant.
(JUMP_TARGET): Likewise.
(FUNC_START): Likewise.
(HIDDEN_FUNC): Likewise.
(FUNC_END): Likeiwse.
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* config.gcc [powerpc*-*-* | rs6000-*-*]: Support --with-abi=elfv1
and --with-abi=elfv2.
* config/rs6000/option-defaults.h (OPTION_DEFAULT_SPECS): Add "abi".
* config/rs6000/rs6000.opt (mabi=elfv1): New option.
(mabi=elfv2): Likewise.
* config/rs6000/rs6000-opts.h (enum rs6000_abi): Add ABI_ELFv2.
* config/rs6000/linux64.h (DEFAULT_ABI): Do not hard-code to AIX_ABI
if !RS6000_BI_ARCH.
(ELFv2_ABI_CHECK): New macro.
(SUBSUBTARGET_OVERRIDE_OPTIONS): Use it to decide whether to set
rs6000_current_abi to ABI_AIX or ABI_ELFv2.
(GLIBC_DYNAMIC_LINKER64): Support ELFv2 ld.so version.
* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Predefine
_CALL_ELF and __STRUCT_PARM_ALIGN__ if appropriate.
* config/rs6000/rs6000.c (rs6000_debug_reg_global): Handle ABI_ELFv2.
(debug_stack_info): Likewise.
(rs6000_file_start): Treat ABI_ELFv2 the same as ABI_AIX.
(rs6000_legitimize_tls_address): Likewise.
(rs6000_conditional_register_usage): Likewise.
(rs6000_emit_move): Likewise.
(init_cumulative_args): Likewise.
(rs6000_function_arg_advance_1): Likewise.
(rs6000_function_arg): Likewise.
(rs6000_arg_partial_bytes): Likewise.
(rs6000_output_function_entry): Likewise.
(rs6000_assemble_integer): Likewise.
(rs6000_savres_strategy): Likewise.
(rs6000_stack_info): Likewise.
(rs6000_function_ok_for_sibcall): Likewise.
(rs6000_emit_load_toc_table): Likewise.
(rs6000_savres_routine_name): Likewise.
(ptr_regno_for_savres): Likewise.
(rs6000_emit_prologue): Likewise.
(rs6000_emit_epilogue): Likewise.
(rs6000_output_function_epilogue): Likewise.
(output_profile_hook): Likewise.
(output_function_profiler): Likewise.
(rs6000_trampoline_size): Likewise.
(rs6000_trampoline_init): Likewise.
(rs6000_elf_output_toc_section_asm_op): Likewise.
(rs6000_elf_encode_section_info): Likewise.
(rs6000_elf_reloc_rw_mask): Likewise.
(rs6000_elf_declare_function_name): Likewise.
(rs6000_function_arg_boundary): Treat ABI_ELFv2 the same as ABI_AIX,
except that rs6000_compat_align_parm is always assumed false.
(rs6000_gimplify_va_arg): Likewise.
(rs6000_call_aix): Update comment.
(rs6000_sibcall_aix): Likewise.
* config/rs6000/rs6000.md ("tls_gd_aix<TLSmode:tls_abi_suffix>"):
Treat ABI_ELFv2 the same as ABI_AIX.
("*tls_gd_call_aix<TLSmode:tls_abi_suffix>"): Likewise.
("tls_ld_aix<TLSmode:tls_abi_suffix>"): Likewise.
("*tls_ld_call_aix<TLSmode:tls_abi_suffix>"): Likewise.
("load_toc_aix_si"): Likewise.
("load_toc_aix_di"): Likewise.
("call"): Likewise.
("call_value"): Likewise.
("*call_local_aix<mode>"): Likewise.
("*call_value_local_aix<mode>"): Likewise.
("*call_nonlocal_aix<mode>"): Likewise.
("*call_value_nonlocal_aix<mode>"): Likewise.
("*call_indirect_aix<mode>"): Likewise.
("*call_value_indirect_aix<mode>"): Likewise.
("sibcall"): Likewise.
("sibcall_value"): Likewise.
("*sibcall_aix<mode>"): Likewise.
("*sibcall_value_aix<mode>"): Likewise.
* config/rs6000/predicates.md ("symbol_ref_operand"): Likewise.
("current_file_function_operand"): Likewise.
gcc/testsuite/ChangeLog:
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* gcc.target/powerpc/ppc64-abi-1.c (stack_frame_t): Remove
compiler and linker field if _CALL_ELF == 2.
* gcc.target/powerpc/ppc64-abi-2.c (stack_frame_t): Likewise.
* gcc.target/powerpc/ppc64-abi-dfp-1.c (stack_frame_t): Likewise.
* gcc.dg/stack-usage-1.c (SIZE): Update value for _CALL_ELF == 2.
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* gcc.target/powerpc/ppc64-abi-dfp-1.c (FUNC_START): New macro.
(WRAPPER): Use it.
* gcc.target/powerpc/no-r11-1.c: Skip on powerpc_elfv2.
* gcc.target/powerpc/no-r11-2.c: Skip on powerpc_elfv2.
* gcc.target/powerpc/no-r11-3.c: Skip on powerpc_elfv2.
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* lib/target-supports.exp (check_effective_target_powerpc_elfv2):
New function.
* gcc.target/powerpc/pr57949-1.c: Disable for powerpc_elfv2.
* gcc.target/powerpc/pr57949-2.c: Likewise.
libgcc/ChangeLog:
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
Alan Modra <amodra@gmail.com>
* config/rs6000/linux-unwind.h (TOC_SAVE_SLOT): Define.
(frob_update_context): Use it.
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
Alan Modra <amodra@gmail.com>
* config/rs6000/tramp.S [__powerpc64__ && _CALL_ELF == 2]:
(trampoline_initial): Provide ELFv2 variant.
(__trampoline_setup): Likewise.
* config/rs6000/linux-unwind.h (frob_update_context): Do not
check for AIX indirect function call sequence if _CALL_ELF == 2.
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
Alan Modra <amodra@gmail.com>
* config/rs6000/linux-unwind.h (get_regs): Do not support
old kernel versions if _CALL_ELF == 2.
(frob_update_context): Do not support PLT stub variants only
generated by old linkers if _CALL_ELF == 2.
libitm/ChangeLog:
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* config/powerpc/sjlj.S [__powerpc64__ && _CALL_ELF == 2]:
(FUNC): Define ELFv2 variant.
(END): Likewise.
(HIDDEN): Likewise.
(CALL): Likewise.
(BASE): Likewise.
(LR_SAVE): Likewise.
libstdc++/ChangeLog:
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* scripts/extract_symvers.in: Ignore <localentry: > fields
in readelf --symbols output.
Co-Authored-By: Alan Modra <amodra@gmail.com>
Co-Authored-By: Michael Gschwind <mkg@us.ibm.com>
From-SVN: r204808
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 24 | ||||
-rw-r--r-- | libgcc/config/rs6000/linux-unwind.h | 40 | ||||
-rw-r--r-- | libgcc/config/rs6000/tramp.S | 66 |
3 files changed, 124 insertions, 6 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index ba72c24..0ba697e 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,6 +1,30 @@ 2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> Alan Modra <amodra@gmail.com> + * config/rs6000/linux-unwind.h (TOC_SAVE_SLOT): Define. + (frob_update_context): Use it. + +2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + Alan Modra <amodra@gmail.com> + + * config/rs6000/tramp.S [__powerpc64__ && _CALL_ELF == 2]: + (trampoline_initial): Provide ELFv2 variant. + (__trampoline_setup): Likewise. + + * config/rs6000/linux-unwind.h (frob_update_context): Do not + check for AIX indirect function call sequence if _CALL_ELF == 2. + +2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + Alan Modra <amodra@gmail.com> + + * config/rs6000/linux-unwind.h (get_regs): Do not support + old kernel versions if _CALL_ELF == 2. + (frob_update_context): Do not support PLT stub variants only + generated by old linkers if _CALL_ELF == 2. + +2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + Alan Modra <amodra@gmail.com> + * config/rs6000/linux-unwind.h (ppc_fallback_frame_state): Correct location of CR save area for 64-bit little-endian systems. diff --git a/libgcc/config/rs6000/linux-unwind.h b/libgcc/config/rs6000/linux-unwind.h index c481e06..a421b15 100644 --- a/libgcc/config/rs6000/linux-unwind.h +++ b/libgcc/config/rs6000/linux-unwind.h @@ -24,9 +24,19 @@ #define R_LR 65 #define R_CR2 70 +#define R_CR3 71 +#define R_CR4 72 #define R_VR0 77 #define R_VRSAVE 109 +#ifdef __powerpc64__ +#if _CALL_ELF == 2 +#define TOC_SAVE_SLOT 24 +#else +#define TOC_SAVE_SLOT 40 +#endif +#endif + struct gcc_vregs { __attribute__ ((vector_size (16))) int vr[32]; @@ -107,6 +117,8 @@ get_regs (struct _Unwind_Context *context) } else if (pc[1] == 0x380000AC) { +#if _CALL_ELF != 2 + /* These old kernel versions never supported ELFv2. */ /* This works for 2.4 kernels, but not for 2.6 kernels with vdso because pc isn't pointing into the stack. Can be removed when no one is running 2.4.19 or 2.4.20, the first two ppc64 @@ -121,6 +133,7 @@ get_regs (struct _Unwind_Context *context) if ((long) frame24->puc != -21 * 8) return frame24->puc->regs; else +#endif { /* This works for 2.4.21 and later kernels. */ struct rt_sigframe { @@ -212,8 +225,16 @@ ppc_fallback_frame_state (struct _Unwind_Context *context, #ifndef __LITTLE_ENDIAN__ cr_offset += sizeof (long) - 4; #endif + /* In the ELFv1 ABI, CR2 stands in for the whole CR. */ fs->regs.reg[R_CR2].how = REG_SAVED_OFFSET; fs->regs.reg[R_CR2].loc.offset = cr_offset; +#if _CALL_ELF == 2 + /* In the ELFv2 ABI, every CR field has a separate CFI entry. */ + fs->regs.reg[R_CR3].how = REG_SAVED_OFFSET; + fs->regs.reg[R_CR3].loc.offset = cr_offset; + fs->regs.reg[R_CR4].how = REG_SAVED_OFFSET; + fs->regs.reg[R_CR4].loc.offset = cr_offset; +#endif fs->regs.reg[R_LR].how = REG_SAVED_OFFSET; fs->regs.reg[R_LR].loc.offset = (long) ®s->link - new_cfa; @@ -297,9 +318,13 @@ frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs ATT figure out if it was saved. The big problem here is that the code that does the save/restore is generated by the linker, so we have no good way to determine at compile time what to do. */ - if (pc[0] == 0xF8410028 + if (pc[0] == 0xF8410000 + TOC_SAVE_SLOT +#if _CALL_ELF != 2 + /* The ELFv2 linker never generates the old PLT stub form. */ || ((pc[0] & 0xFFFF0000) == 0x3D820000 - && pc[1] == 0xF8410028)) + && pc[1] == 0xF8410000 + TOC_SAVE_SLOT) +#endif + ) { /* We are in a plt call stub or r2 adjusting long branch stub, before r2 has been saved. Keep REG_UNSAVED. */ @@ -308,18 +333,21 @@ frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs ATT { unsigned int *insn = (unsigned int *) _Unwind_GetGR (context, R_LR); - if (insn && *insn == 0xE8410028) - _Unwind_SetGRPtr (context, 2, context->cfa + 40); + if (insn && *insn == 0xE8410000 + TOC_SAVE_SLOT) + _Unwind_SetGRPtr (context, 2, context->cfa + TOC_SAVE_SLOT); +#if _CALL_ELF != 2 + /* ELFv2 does not use this function pointer call sequence. */ else if (pc[0] == 0x4E800421 - && pc[1] == 0xE8410028) + && pc[1] == 0xE8410000 + TOC_SAVE_SLOT) { /* We are at the bctrl instruction in a call via function pointer. gcc always emits the load of the new R2 just before the bctrl so this is the first and only place we need to use the stored R2. */ _Unwind_Word sp = _Unwind_GetGR (context, 1); - _Unwind_SetGRPtr (context, 2, (void *)(sp + 40)); + _Unwind_SetGRPtr (context, 2, (void *)(sp + TOC_SAVE_SLOT)); } +#endif } } #endif diff --git a/libgcc/config/rs6000/tramp.S b/libgcc/config/rs6000/tramp.S index 14cb18d..fe2a454 100644 --- a/libgcc/config/rs6000/tramp.S +++ b/libgcc/config/rs6000/tramp.S @@ -116,4 +116,70 @@ FUNC_END(__trampoline_setup) #endif +#elif _CALL_ELF == 2 + .type trampoline_initial,@object + .align 3 +trampoline_initial: + ld r11,.Lchain(r12) + ld r12,.Lfunc(r12) + mtctr r12 + bctr +.Lfunc = .-trampoline_initial + .quad 0 /* will be replaced with function address */ +.Lchain = .-trampoline_initial + .quad 0 /* will be replaced with static chain */ + +trampoline_size = .-trampoline_initial + .size trampoline_initial,trampoline_size + + +/* R3 = stack address to store trampoline */ +/* R4 = length of trampoline area */ +/* R5 = function address */ +/* R6 = static chain */ + + .pushsection ".toc","aw" +.LC0: + .quad trampoline_initial-8 + .popsection + +FUNC_START(__trampoline_setup) + addis 7,2,.LC0@toc@ha + ld 7,.LC0@toc@l(7) /* trampoline address -8 */ + + li r8,trampoline_size /* verify that the trampoline is big enough */ + cmpw cr1,r8,r4 + srwi r4,r4,3 /* # doublewords to move */ + addi r9,r3,-8 /* adjust pointer for stdu */ + mtctr r4 + blt cr1,.Labort + + /* Copy the instructions to the stack */ +.Lmove: + ldu r10,8(r7) + stdu r10,8(r9) + bdnz .Lmove + + /* Store correct function and static chain */ + std r5,.Lfunc(r3) + std r6,.Lchain(r3) + + /* Now flush both caches */ + mtctr r4 +.Lcache: + icbi 0,r3 + dcbf 0,r3 + addi r3,r3,8 + bdnz .Lcache + + /* Finally synchronize things & return */ + sync + isync + blr + +.Labort: + bl JUMP_TARGET(abort) + nop +FUNC_END(__trampoline_setup) + #endif |