Commit e8dc4658 by Richard Henderson Committed by Richard Henderson

Cleanup 32-bit ms_hook code.

Emit the entire required hook code sequence via ASM_BYTE; emit
unwind info onto a blockage insn.

Remove the vswapmov pattern.

Fix indentation in several places.

From-SVN: r162886
parent 25502041
2010-08-04 Richard Henderson <rth@redhat.com> 2010-08-04 Richard Henderson <rth@redhat.com>
* config/i386/i386.c (ix86_function_ms_hook_prologue): Fix
argument name to reflect the expected tree; fix indentation.
(ix86_asm_output_function_label): Output the entire 32-bit
ms_hook here as bytes ...
(ix86_expand_prologue): ... not here as insns. Attach the
unwind info for the ms_hook to a blockage insn.
(ix86_handle_fndecl_attribute): Don't check HAVE_AS_IX86_SWAP.
(ix86_ms_bitfield_layout_p): Fix indentation.
* config/i386/i386.md (UNSPECV_VSWAPMOV, vswapmov): Remove.
* config/i386/i386.c (ix86_using_red_zone): New. * config/i386/i386.c (ix86_using_red_zone): New.
(ix86_compute_frame_layout, ix86_add_cfa_restore_note, (ix86_compute_frame_layout, ix86_add_cfa_restore_note,
ix86_expand_prologue, ix86_force_to_memory): Use it. ix86_expand_prologue, ix86_force_to_memory): Use it.
......
...@@ -5117,17 +5117,15 @@ ix86_function_type_abi (const_tree fntype) ...@@ -5117,17 +5117,15 @@ ix86_function_type_abi (const_tree fntype)
} }
static bool static bool
ix86_function_ms_hook_prologue (const_tree fntype) ix86_function_ms_hook_prologue (const_tree fn)
{ {
if (fntype && lookup_attribute ("ms_hook_prologue", DECL_ATTRIBUTES (fntype))) if (fn && lookup_attribute ("ms_hook_prologue", DECL_ATTRIBUTES (fn)))
{ {
if (decl_function_context (fntype) != NULL_TREE) if (decl_function_context (fn) != NULL_TREE)
{ error_at (DECL_SOURCE_LOCATION (fn),
error_at (DECL_SOURCE_LOCATION (fntype), "ms_hook_prologue is not compatible with nested function");
"ms_hook_prologue is not compatible with nested function"); else
} return true;
return true;
} }
return false; return false;
} }
...@@ -5169,18 +5167,23 @@ ix86_asm_output_function_label (FILE *asm_out_file, const char *fname, ...@@ -5169,18 +5167,23 @@ ix86_asm_output_function_label (FILE *asm_out_file, const char *fname,
ASM_OUTPUT_LABEL (asm_out_file, fname); ASM_OUTPUT_LABEL (asm_out_file, fname);
/* Output magic byte marker, if hot-patch attribute is set. /* Output magic byte marker, if hot-patch attribute is set. */
For x86 case frame-pointer prologue will be emitted in
expand_prologue. */
if (is_ms_hook) if (is_ms_hook)
{ {
if (TARGET_64BIT) if (TARGET_64BIT)
/* leaq [%rsp + 0], %rsp */ {
asm_fprintf (asm_out_file, ASM_BYTE /* leaq [%rsp + 0], %rsp */
"0x48, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00\n"); asm_fprintf (asm_out_file, ASM_BYTE
"0x48, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00\n");
}
else else
/* movl.s %edi, %edi. */ {
asm_fprintf (asm_out_file, ASM_BYTE "0x8b, 0xff\n"); /* movl.s %edi, %edi
push %ebp
movl.s %esp, %ebp */
asm_fprintf (asm_out_file, ASM_BYTE
"0x8b, 0xff, 0x55, 0x8b, 0xec\n");
}
} }
} }
...@@ -9200,7 +9203,7 @@ ix86_expand_prologue (void) ...@@ -9200,7 +9203,7 @@ ix86_expand_prologue (void)
bool pic_reg_used; bool pic_reg_used;
struct ix86_frame frame; struct ix86_frame frame;
HOST_WIDE_INT allocate; HOST_WIDE_INT allocate;
int gen_frame_pointer = frame_pointer_needed; bool gen_frame_pointer = frame_pointer_needed;
bool int_registers_saved = false; bool int_registers_saved = false;
ix86_finalize_stack_realign_flags (); ix86_finalize_stack_realign_flags ();
...@@ -9216,51 +9219,78 @@ ix86_expand_prologue (void) ...@@ -9216,51 +9219,78 @@ ix86_expand_prologue (void)
if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl)) if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
{ {
rtx push, mov; /* We should have already generated an error for any use of
ms_hook on a nested function. */
gcc_checking_assert (!ix86_static_chain_on_stack);
/* Check if profiling is active and we shall use profiling before /* Check if profiling is active and we shall use profiling before
prologue variant. If so sorry. */ prologue variant. If so sorry. */
if (crtl->profile && flag_fentry != 0) if (crtl->profile && flag_fentry != 0)
sorry ("ms_hook_prologue attribute isn't compatible with -mfentry for 32-bit"); sorry ("ms_hook_prologue attribute isn't compatible with -mfentry for 32-bit");
/* Make sure the function starts with /* In ix86_asm_output_function_label we emitted:
8b ff movl.s %edi,%edi (emited by ix86_asm_output_function_label) 8b ff movl.s %edi,%edi
55 push %ebp 55 push %ebp
8b ec movl.s %esp,%ebp 8b ec movl.s %esp,%ebp
This matches the hookable function prologue in Win32 API This matches the hookable function prologue in Win32 API
functions in Microsoft Windows XP Service Pack 2 and newer. functions in Microsoft Windows XP Service Pack 2 and newer.
Wine uses this to enable Windows apps to hook the Win32 API Wine uses this to enable Windows apps to hook the Win32 API
functions provided by Wine. */ functions provided by Wine.
push = emit_insn (gen_push (hard_frame_pointer_rtx));
mov = emit_insn (gen_vswapmov (hard_frame_pointer_rtx,
stack_pointer_rtx));
if (frame_pointer_needed && !(crtl->drap_reg What that means is that we've already set up the frame pointer. */
&& crtl->stack_realign_needed))
if (frame_pointer_needed
&& !(crtl->drap_reg && crtl->stack_realign_needed))
{ {
/* The push %ebp and movl.s %esp, %ebp already set up rtx push, mov;
the frame pointer. No need to do this again. */
gen_frame_pointer = 0; /* We've decided to use the frame pointer already set up.
Describe this to the unwinder by pretending that both
push and mov insns happen right here.
Putting the unwind info here at the end of the ms_hook
is done so that we can make absolutely certain we get
the required byte sequence at the start of the function,
rather than relying on an assembler that can produce
the exact encoding required.
However it does mean (in the unpatched case) that we have
a 1 insn window where the asynchronous unwind info is
incorrect. However, if we placed the unwind info at
its correct location we would have incorrect unwind info
in the patched case. Which is probably all moot since
I don't expect Wine generates dwarf2 unwind info for the
system libraries that use this feature. */
insn = emit_insn (gen_blockage ());
push = gen_push (hard_frame_pointer_rtx);
mov = gen_rtx_SET (VOIDmode, hard_frame_pointer_rtx,
stack_pointer_rtx);
RTX_FRAME_RELATED_P (push) = 1; RTX_FRAME_RELATED_P (push) = 1;
RTX_FRAME_RELATED_P (mov) = 1; RTX_FRAME_RELATED_P (mov) = 1;
RTX_FRAME_RELATED_P (insn) = 1;
add_reg_note (insn, REG_FRAME_RELATED_EXPR,
gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, push, mov)));
if (ix86_cfa_state->reg == stack_pointer_rtx) if (ix86_cfa_state->reg == stack_pointer_rtx)
ix86_cfa_state->reg = hard_frame_pointer_rtx; ix86_cfa_state->reg = hard_frame_pointer_rtx;
gen_frame_pointer = false;
} }
else else
/* If the frame pointer is not needed, pop %ebp again. This {
could be optimized for cases where ebp needs to be backed up /* The frame pointer is not needed so pop %ebp again.
for some other reason. If stack realignment is needed, pop This leaves us with a pristine state. */
the base pointer again, align the stack, and later regenerate emit_insn (ix86_gen_pop1 (hard_frame_pointer_rtx));
the frame pointer setup. The frame pointer generated by the }
hook prologue is not aligned, so it can't be used. */
insn = emit_insn (ix86_gen_pop1 (hard_frame_pointer_rtx));
} }
/* The first insn of a function that accepts its static chain on the /* The first insn of a function that accepts its static chain on the
stack is to push the register that would be filled in by a direct stack is to push the register that would be filled in by a direct
call. This insn will be skipped by the trampoline. */ call. This insn will be skipped by the trampoline. */
if (ix86_static_chain_on_stack) else if (ix86_static_chain_on_stack)
{ {
rtx t; rtx t;
...@@ -27010,23 +27040,16 @@ ix86_handle_fndecl_attribute (tree *node, tree name, ...@@ -27010,23 +27040,16 @@ ix86_handle_fndecl_attribute (tree *node, tree name,
warning (OPT_Wattributes, "%qE attribute only applies to functions", warning (OPT_Wattributes, "%qE attribute only applies to functions",
name); name);
*no_add_attrs = true; *no_add_attrs = true;
return NULL_TREE;
} }
return NULL_TREE;
#ifndef HAVE_AS_IX86_SWAP
if (!TARGET_64BIT)
sorry ("ms_hook_prologue attribute needs assembler swap suffix support");
#endif
return NULL_TREE;
} }
static bool static bool
ix86_ms_bitfield_layout_p (const_tree record_type) ix86_ms_bitfield_layout_p (const_tree record_type)
{ {
return (TARGET_MS_BITFIELD_LAYOUT && return ((TARGET_MS_BITFIELD_LAYOUT
!lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type))) && !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
|| lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type)); || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type)));
} }
/* Returns an expression indicating where the this parameter is /* Returns an expression indicating where the this parameter is
......
...@@ -250,7 +250,6 @@ ...@@ -250,7 +250,6 @@
UNSPECV_RDTSC UNSPECV_RDTSC
UNSPECV_RDTSCP UNSPECV_RDTSCP
UNSPECV_RDPMC UNSPECV_RDPMC
UNSPECV_VSWAPMOV
UNSPECV_LLWP_INTRINSIC UNSPECV_LLWP_INTRINSIC
UNSPECV_SLWP_INTRINSIC UNSPECV_SLWP_INTRINSIC
UNSPECV_LWPVAL_INTRINSIC UNSPECV_LWPVAL_INTRINSIC
...@@ -11573,16 +11572,6 @@ ...@@ -11573,16 +11572,6 @@
(set_attr "length_immediate" "0") (set_attr "length_immediate" "0")
(set_attr "modrm" "0")]) (set_attr "modrm" "0")])
(define_insn "vswapmov"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operand:SI 1 "register_operand" "r"))
(unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
""
"movl.s\t{%1, %0|%0, %1}"
[(set_attr "length" "2")
(set_attr "length_immediate" "0")
(set_attr "modrm" "0")])
;; Pad to 16-byte boundary, max skip in op0. Used to avoid ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
;; branch prediction penalty for the third jump in a 16-byte ;; branch prediction penalty for the third jump in a 16-byte
;; block on K8. ;; block on K8.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment