This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] improve internals documentation for nested function descriptors


Apropos of the discussion about improving the docs for TARGET_CUSTOM_FUNCTION_DESCRIPTORS in the context of the C-SKY port submission,

https://gcc.gnu.org/ml/gcc-patches/2018-07/msg01454.html

here is the patch I've come up with based on reading the source. Is this technically accurate? Any suggestions on how to improve it further?

-Sandra
2018-07-27  Sandra Loosemore  <sandra@codesourcery.com>

	gcc/
	* target.def (custom_function_descriptors): Improve documentation.
	* doc/tm.texi.in (Trampolines): Expand discussion of function
	descriptors and move TARGET_CUSTOM_FUNCTION_DESCRIPTORS to the
	beginning of the section.
	* doc/tm.texi: Regenerated.
diff --git a/gcc/target.def b/gcc/target.def
index 112c772..d67228d 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -4966,21 +4966,21 @@ If this hook is not defined, @var{addr} will be used for function calls.",
 
 DEFHOOKPOD
 (custom_function_descriptors,
- "This hook should be defined to a power of 2 if the target will benefit\n\
-from the use of custom descriptors for nested functions instead of the\n\
-standard trampolines.  Such descriptors are created at run time on the\n\
-stack and made up of data only, but they are non-standard so the generated\n\
-code must be prepared to deal with them.  This hook should be defined to 0\n\
-if the target uses function descriptors for its standard calling sequence,\n\
-like for example HP-PA or IA-64.  Using descriptors for nested functions\n\
+ "Define this hook to 0 if the target implements custom support for\n\
+function descriptors in its standard calling sequence, like for example\n\
+HPPA or IA-64.\n\
+\n\
+If the target can use GCC's generic descriptor mechanism for nested\n\
+functions, define this hook to a power of 2 representing an unused bit\n\
+in function pointers which can be used to tag descriptors and\n\
+differentiate them at run time.  For example, on targets that require\n\
+functions to be word-aligned, a value of either 1 or 2 is appropriate\n\
+unless the architecture already reserves the bit for another purpose,\n\
+such as on ARM.\n\
+\n\
+Using descriptors for nested functions\n\
 eliminates the need for trampolines that reside on the stack and require\n\
-it to be made executable.\n\
-\n\
-The value of the macro is used to parameterize the run-time identification\n\
-scheme implemented to distinguish descriptors from function addresses: it\n\
-gives the number of bytes by which their address is misaligned compared\n\
-with function addresses.  The value of 1 will generally work, unless it is\n\
-already reserved by the target for another purpose, like for example on ARM.",\
+it to be made executable.",\
  int, -1)
 
 /* Return the number of bytes of its own arguments that a function
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index b7b0e8a..e15b604 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3766,24 +3766,60 @@ These machine description macros help implement varargs:
 @hook TARGET_SETUP_INCOMING_VARARG_BOUNDS
 
 @node Trampolines
-@section Trampolines for Nested Functions
+@section Support for Nested Functions
+@cindex support for nested functions
 @cindex trampolines for nested functions
-@cindex nested functions, trampolines for
-
-A @dfn{trampoline} is a small piece of code that is created at run time
-when the address of a nested function is taken.  It normally resides on
-the stack, in the stack frame of the containing function.  These macros
-tell GCC how to generate code to allocate and initialize a
-trampoline.
-
-The instructions in the trampoline must do two things: load a constant
-address into the static chain register, and jump to the real address of
-the nested function.  On CISC machines such as the m68k, this requires
-two instructions, a move immediate and a jump.  Then the two addresses
-exist in the trampoline as word-long immediate operands.  On RISC
-machines, it is often necessary to load each address into a register in
-two parts.  Then pieces of each address form separate immediate
-operands.
+@cindex descriptors for nested functions
+@cindex nested functions, support for
+
+Taking the address of a nested function requires special compiler
+handling to ensure that the static chain register is loaded when
+the function is invoked via an indirect call.
+
+GCC has traditionally supported nested functions by creating an
+executable @dfn{trampoline} at run time when the address of a nested
+function is taken.  This is a small piece of code which normally
+resides on the stack, in the stack frame of the containing function.
+The trampoline loads the static chain register and then jumps to the
+real address of the nested function.
+
+The use of trampolines requires an executable stack, which is a
+security risk.  To avoid this problem, GCC also supports another
+strategy: using descriptors for nested functions.  Under this model,
+taking the address of a nested function results in a pointer to a
+non-executable function descriptor object.  Initializing the static chain
+from the descriptor is handled at indirect call sites.
+
+On some targets, including HPPA and IA-64, function descriptors may be
+mandated by the ABI or be otherwise handled in a target-specific way
+by the back end in its code generation strategy for indirect calls.
+GCC also supports a generic mechanism to implement the
+@option{-fno-trampolines} option by generating descriptors for nested
+functions.  In this case runtime detection of function descriptors at
+indirect call sites relies on descriptor pointers being tagged with a
+bit that is never set in bare function addresses.  Since using the
+generic function descriptors is generally not ABI-compliant, this
+option is typically used only on a per-language basis (notably by Ada)
+or when it can otherwise be applied to the whole program.
+
+Define the following hook if your backend either implements its own custom
+nested descriptor support, or can use GCC's generic descriptor support.
+
+@hook TARGET_CUSTOM_FUNCTION_DESCRIPTORS
+
+The following macros tell GCC how to generate code to allocate and
+initialize an executable trampoline.  You can also use this interface
+if your back end needs to create custom non-executable descriptors; in
+this case the "trampoline" created is the descriptor containing data only.
+
+The instructions in an executable trampoline must do two things: load
+a constant ddress into the static chain register, and jump to the real
+address of the nested function.  On CISC machines such as the m68k,
+this requires two instructions, a move immediate and a jump.  Then the
+two addresses exist in the trampoline as word-long immediate operands.
+On RISC machines, it is often necessary to load each address into a
+register in two parts.  Then pieces of each address form separate
+immediate operands.
 
 The code generated to initialize the trampoline must store the variable
 parts---the static chain value and the function address---into the
@@ -3815,8 +3851,6 @@ is used for aligning trampolines.
 
 @hook TARGET_TRAMPOLINE_ADJUST_ADDRESS
 
-@hook TARGET_CUSTOM_FUNCTION_DESCRIPTORS
-
 Implementing trampolines is difficult on many machines because they have
 separate instruction and data caches.  Writing into a stack location
 fails to clear the memory in the instruction cache, so when the program
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 7e2cdc2..210e394 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5267,24 +5267,76 @@ into the stack.  Arguments meaning is similar to
 @end deftypefn
 
 @node Trampolines
-@section Trampolines for Nested Functions
+@section Support for Nested Functions
+@cindex support for nested functions
 @cindex trampolines for nested functions
-@cindex nested functions, trampolines for
-
-A @dfn{trampoline} is a small piece of code that is created at run time
-when the address of a nested function is taken.  It normally resides on
-the stack, in the stack frame of the containing function.  These macros
-tell GCC how to generate code to allocate and initialize a
-trampoline.
-
-The instructions in the trampoline must do two things: load a constant
-address into the static chain register, and jump to the real address of
-the nested function.  On CISC machines such as the m68k, this requires
-two instructions, a move immediate and a jump.  Then the two addresses
-exist in the trampoline as word-long immediate operands.  On RISC
-machines, it is often necessary to load each address into a register in
-two parts.  Then pieces of each address form separate immediate
-operands.
+@cindex descriptors for nested functions
+@cindex nested functions, support for
+
+Taking the address of a nested function requires special compiler
+handling to ensure that the static chain register is loaded when
+the function is invoked via an indirect call.
+
+GCC has traditionally supported nested functions by creating an
+executable @dfn{trampoline} at run time when the address of a nested
+function is taken.  This is a small piece of code which normally
+resides on the stack, in the stack frame of the containing function.
+The trampoline loads the static chain register and then jumps to the
+real address of the nested function.
+
+The use of trampolines requires an executable stack, which is a
+security risk.  To avoid this problem, GCC also supports another
+strategy: using descriptors for nested functions.  Under this model,
+taking the address of a nested function results in a pointer to a
+non-executable function descriptor object.  Initializing the static chain
+from the descriptor is handled at indirect call sites.
+
+On some targets, including HPPA and IA-64, function descriptors may be
+mandated by the ABI or be otherwise handled in a target-specific way
+by the back end in its code generation strategy for indirect calls.
+GCC also supports a generic mechanism to implement the
+@option{-fno-trampolines} option by generating descriptors for nested
+functions.  In this case runtime detection of function descriptors at
+indirect call sites relies on descriptor pointers being tagged with a
+bit that is never set in bare function addresses.  Since using the
+generic function descriptors is generally not ABI-compliant, this
+option is typically used only on a per-language basis (notably by Ada)
+or when it can otherwise be applied to the whole program.
+
+Define the following hook if your backend either implements its own custom
+nested descriptor support, or can use GCC's generic descriptor support.
+
+@deftypevr {Target Hook} int TARGET_CUSTOM_FUNCTION_DESCRIPTORS
+Define this hook to 0 if the target implements custom support for
+function descriptors in its standard calling sequence, like for example
+HPPA or IA-64.
+
+If the target can use GCC's generic descriptor mechanism for nested
+functions, define this hook to a power of 2 representing an unused bit
+in function pointers which can be used to tag descriptors and
+differentiate them at run time.  For example, on targets that require
+functions to be word-aligned, a value of either 1 or 2 is appropriate
+unless the architecture already reserves the bit for another purpose,
+such as on ARM.
+
+Using descriptors for nested functions
+eliminates the need for trampolines that reside on the stack and require
+it to be made executable.
+@end deftypevr
+
+The following macros tell GCC how to generate code to allocate and
+initialize an executable trampoline.  You can also use this interface
+if your back end needs to create custom non-executable descriptors; in
+this case the "trampoline" created is the descriptor containing data only.
+
+The instructions in an executable trampoline must do two things: load
+a constant ddress into the static chain register, and jump to the real
+address of the nested function.  On CISC machines such as the m68k,
+this requires two instructions, a move immediate and a jump.  Then the
+two addresses exist in the trampoline as word-long immediate operands.
+On RISC machines, it is often necessary to load each address into a
+register in two parts.  Then pieces of each address form separate
+immediate operands.
 
 The code generated to initialize the trampoline must store the variable
 parts---the static chain value and the function address---into the
@@ -5351,24 +5403,6 @@ be returned; otherwise @var{addr} should be returned unchanged.
 If this hook is not defined, @var{addr} will be used for function calls.
 @end deftypefn
 
-@deftypevr {Target Hook} int TARGET_CUSTOM_FUNCTION_DESCRIPTORS
-This hook should be defined to a power of 2 if the target will benefit
-from the use of custom descriptors for nested functions instead of the
-standard trampolines.  Such descriptors are created at run time on the
-stack and made up of data only, but they are non-standard so the generated
-code must be prepared to deal with them.  This hook should be defined to 0
-if the target uses function descriptors for its standard calling sequence,
-like for example HP-PA or IA-64.  Using descriptors for nested functions
-eliminates the need for trampolines that reside on the stack and require
-it to be made executable.
-
-The value of the macro is used to parameterize the run-time identification
-scheme implemented to distinguish descriptors from function addresses: it
-gives the number of bytes by which their address is misaligned compared
-with function addresses.  The value of 1 will generally work, unless it is
-already reserved by the target for another purpose, like for example on ARM.
-@end deftypevr
-
 Implementing trampolines is difficult on many machines because they have
 separate instruction and data caches.  Writing into a stack location
 fails to clear the memory in the instruction cache, so when the program

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]