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 <san...@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