This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH v2] gas: Improve documentation for cfi_remember/restore_state
- From: Martin Galvan <martin dot galvan at tallertechnologies dot com>
- To: binutils at sourceware dot org, amodra at gmail dot com, nickc at redhat dot com
- Date: Mon, 18 Apr 2016 16:11:40 -0300
- Subject: [PATCH v2] gas: Improve documentation for cfi_remember/restore_state
- Authentication-results: sourceware.org; auth=none
The previous documentation for these CFI directives wasn't very helpful, so I
reworded it and added an example. Any feedback is welcome.
I have a company-wide copyright assignment for binutils, but I don't have write
access so someone else should commit this for me. Thanks!
gas/ChangeLog:
2016-04-18 Martin Galvan <martin.galvan@tallertechnologies.com>
* doc/as.texinfo (.cfi_remember_state, .cfi_restore_state): Improve
documentation.
---
gas/doc/as.texinfo | 53 ++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 48 insertions(+), 5 deletions(-)
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index 7b36931..e2e744e 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -4816,11 +4816,54 @@ From now on the previous value of @var{register} can't be restored anymore.
Current value of @var{register} is the same like in the previous frame,
i.e. no restoration needed.
-@subsection @code{.cfi_remember_state},
-First save all current rules for all registers by @code{.cfi_remember_state},
-then totally screw them up by subsequent @code{.cfi_*} directives and when
-everything is hopelessly bad, use @code{.cfi_restore_state} to restore
-the previous saved state.
+@subsection @code{.cfi_remember_state} and @code{.cfi_restore_state}
+@code{.cfi_remember_state} pushes the set of rules for every register onto an
+implicit stack, while @code{.cfi_restore_state} pops them off the stack and
+places them in the current row. This is useful for situations where you have
+multiple @code{.cfi_*} directives that need to be undone due to the control
+flow of the program. For example, we could have something like this (assuming
+the CFA is the value of @code{rbp}):
+
+@smallexample
+ je label
+ popq %rbx
+ .cfi_restore %rbx
+ popq %r12
+ .cfi_restore %r12
+ popq %rbp
+ .cfi_restore %rbp
+ .cfi_def_cfa %rsp, 8
+ ret
+label:
+ /* Do something else */
+@end smallexample
+
+Here, we want the @code{.cfi} directives to affect only the rows corresponding
+to the instructions before @code{label}. This means we'd have to add multiple
+@code{.cfi} directives after @code{label} to recreate the original save
+locations of the registers, as well as setting the CFA back to the value of
+@code{rbp}. This would be clumsy, and result in a larger binary size. Instead,
+we can write:
+
+@smallexample
+ je label
+ popq %rbx
+ .cfi_remember_state
+ .cfi_restore %rbx
+ popq %r12
+ .cfi_restore %r12
+ popq %rbp
+ .cfi_restore %rbp
+ .cfi_def_cfa %rsp, 8
+ ret
+label:
+ .cfi_restore_state
+ /* Do something else */
+@end smallexample
+
+That way, the rules for the instructions after @code{label} will be the same
+as before the first @code{.cfi_restore} without having to use multiple
+@code{.cfi} directives.
@subsection @code{.cfi_return_column @var{register}}
Change return column @var{register}, i.e. the return address is either
--
2.8.1