diff options
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r-- | gcc/varasm.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c index fbaebc1b5c0..6eccbe4b3f7 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -1825,6 +1825,46 @@ assemble_start_function (tree decl, const char *fnname) if (DECL_PRESERVE_P (decl)) targetm.asm_out.mark_decl_preserved (fnname); + unsigned HOST_WIDE_INT patch_area_size = function_entry_patch_area_size; + unsigned HOST_WIDE_INT patch_area_entry = function_entry_patch_area_start; + + tree patchable_function_entry_attr + = lookup_attribute ("patchable_function_entry", DECL_ATTRIBUTES (decl)); + if (patchable_function_entry_attr) + { + tree pp_val = TREE_VALUE (patchable_function_entry_attr); + tree patchable_function_entry_value1 = TREE_VALUE (pp_val); + + if (tree_fits_uhwi_p (patchable_function_entry_value1)) + patch_area_size = tree_to_uhwi (patchable_function_entry_value1); + else + gcc_unreachable (); + + patch_area_entry = 0; + if (list_length (pp_val) > 1) + { + tree patchable_function_entry_value2 = + TREE_VALUE (TREE_CHAIN (pp_val)); + + if (tree_fits_uhwi_p (patchable_function_entry_value2)) + patch_area_entry = tree_to_uhwi (patchable_function_entry_value2); + else + gcc_unreachable (); + } + } + + if (patch_area_entry > patch_area_size) + { + if (patch_area_size > 0) + warning (OPT_Wattributes, "Patchable function entry > size"); + patch_area_entry = 0; + } + + /* Emit the patching area before the entry label, if any. */ + if (patch_area_entry > 0) + targetm.asm_out.print_patchable_function_entry (asm_out_file, + patch_area_entry, true); + /* Do any machine/system dependent processing of the function name. */ #ifdef ASM_DECLARE_FUNCTION_NAME ASM_DECLARE_FUNCTION_NAME (asm_out_file, fnname, current_function_decl); @@ -1833,6 +1873,12 @@ assemble_start_function (tree decl, const char *fnname) ASM_OUTPUT_FUNCTION_LABEL (asm_out_file, fnname, current_function_decl); #endif /* ASM_DECLARE_FUNCTION_NAME */ + /* And the area after the label. Record it if we haven't done so yet. */ + if (patch_area_size > patch_area_entry) + targetm.asm_out.print_patchable_function_entry (asm_out_file, + patch_area_size-patch_area_entry, + patch_area_entry == 0); + if (lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (decl))) saw_no_split_stack = true; } @@ -2403,7 +2449,7 @@ assemble_external (tree decl ATTRIBUTE_UNUSED) gcc_assert (asm_out_file); /* In a perfect world, the following condition would be true. - Sadly, the Java and Go front ends emit assembly *from the front end*, + Sadly, the Go front end emit assembly *from the front end*, bypassing the call graph. See PR52739. Fix before GCC 4.8. */ #if 0 /* This function should only be called if we are expanding, or have |